Add value to Firebase (AngularFire) - firebase

I try to add new value to database but I do not know how to add without generating the unique key (Highlighted part)
Here is what I have done so far. Any help would be appreciated!
var newRef = GetArrayFactory('users',firebaseUser.uid); //reference to '5QMI4UsOeAXZUxxkuy5jozcrrSK2'
newRef.$add(
{ 'email': email }
).then(function(newRef){
var id = newRef.key;
console.log("added record with id " + id);
list.$indexFor(id); // returns location in the array
});

Related

How can I use AQL with multiple queries that using the result of one another?

I have 2 vertices and an edge named user, device, ownership respectively.
My business logic is when I receive device information, I upsert it with dateCreated and dateUpdated fields added. If I inserted that device then I insert new user with default values and create edge connection to it. If I update I simple return already connected user as a result.
Without losing atomicity how can I achieve this?
I tried single AQL query but without condition it is not possible it seems and traversal also is not supported with insert/update operation.
I can do separate queries but that loses atomicity.
var finalQuery = aql`
UPSERT ${deviceQuery}
INSERT MERGE(${deviceQuery},{dateCreated:DATE_NOW()})
UPDATE MERGE(${deviceQuery},{dateUpdated:DATE_NOW()})
IN ${this.DeviceModel}
RETURN { doc: NEW, type: OLD ? 'update' : 'insert' }`;
var cursor = await db.query(finalQuery);
var result = await cursor.next();
if (result.type == 'insert') {
console.log('Inserted documents')
finalQuery = aql`
LET user=(INSERT {
"_key":UUID(),
"name": "User"
} INTO user
RETURN NEW)
INSERT {
_from:${result.doc._id},
_to:user[0]._id,
"type": "belongs"
}INTO ownership
return user[0]`;
cursor = await db.query(finalQuery);
result = await cursor.next();
console.log('New user:',result);
}
You can try something like this
Upsert ....
FILTER !OLD
Let model = NEW
LET user= First(INSERT {
"_key":UUID(),
"name": "User"
} INTO user
RETURN NEW)
INSERT {
_from:model._id,
_to:user._id,
"type": "belongs"
}INTO ownership
return user
I end up separating the modification and selection queries.
var finalQuery = aql`
LET device=(
UPSERT ${deviceQuery}
INSERT MERGE(${deviceQuery},{dateCreated:DATE_NOW()})
UPDATE MERGE(${deviceQuery},{dateUpdated:DATE_NOW()})
IN ${this.DeviceModel}
RETURN { doc: NEW, type: OLD ? 'update' : 'insert' })
FILTER device[0].type=='insert'
LET user=(INSERT {
"_key":UUID(),
"name": "User"
} INTO user
RETURN NEW)
INSERT {
_from:device[0].doc._id,
_to:user[0]._id,
"type": "belongs"
}INTO ownership
return user[0]`;
var cursor = await db.query(finalQuery);
var result = await cursor.next();
if (result == null) {
const deviceId=this.DeviceModel.name+"/"+queryParams._key;
finalQuery = aql`
FOR v,e,p IN 1..1
OUTBOUND ${deviceId} ownership
FILTER e.type=="belongs"
RETURN v `;
cursor = await db.query(finalQuery);
result = await cursor.next();
isUpdate=true;
}
This way I ensure the atomicity. There are improvements for controling if cursor.extra.stats.writesExecuted true etc.

firebase realtime database find node by child value

I have the following structure:
root
-LKMsdf2_Qxbwtv4238D
details
uid: john
-YKMWrmj_QxbwtvSBM5A
details
uid: tony
-R45Wrmj_Qxbf321BMd4
details
uid: karina
How can I find the ref key under 'root' by its uid:
e.g: by uid:karina I need to get the ref key -R45Wrmj_Qxbf321BMd4
is there a way to use some wildcard like /root/{recordid}/details/uid or something?
======== Thanks for the hints! ==== here is my final solution ================
findEntry = function(targetUid) {
var entriesRef = db.ref('root');
return entriesRef.once('value')
.then((snapshot)=>{
var id = []; // found id
snapshot.forEach((childSnapshot)=>{
var childKey = childSnapshot.key;
var childData = childSnapshot.val();
var found = (childData.uid === targetUid);
if (found) {
console.log('Found for uid:' + targetUid + ': ' + childKey);
id = childKey;
}
return found; // true - breaks the forEach, false - continue
});
if (!id) {
console.log('Not Found for uid:' + targetUid);
}
return id;
});
}
No, the best you can do is child (key) search and equality (see the example here https://firebase.google.com/docs/reference/js/firebase.database.Query#equalTo)
// Find all dinosaurs whose height is exactly 25 meters.
var ref = firebase.database().ref("dinosaurs");
ref.orderByChild("height").equalTo(25).on("child_added", function(snapshot) {
console.log(snapshot.key);
});
There isn't a way to query deeper than that.
You could have other structures for reverse lookups, flatten out your data or solve it in a different way.

Checking a child's entries for a match

let ref = firebase.database().ref('players').child(playerId).child('voters');
ref.child(uid).once('value', snap => {
var key = snap.key;
console.log("snapkey: " + key + " uid: " + uid)
if (key === uid) {
console.log("Exists")
} else {
console.log("Doesn't exist")
}
});
I'm trying to see if a variable uid, which holds the users unique ID from firebase-auth is present in my database's voters
So for me, when I'm using the app, my uid is vKl6rIUuI0WsbeWVORz3twPUfnd2. So if I go to vote on this Firstname Lastname person, it should tell me I exist in the above image's scenario.
The problem is, it seems to always say it exists. The console.log for key and uid are both putting out my uid. Is it something with the ref.child(uid)...?
let ref = firebase.database().ref('/players/' + playerID + '/voters');
ref.once('value', snap => {
var value = snap.val()
console.log(value)
if (value !== null) {
console.log("Exists")
} else {
console.log("Doesn't exist")
}
});
https://firebase.google.com/docs/database/web/read-and-write#read_data_once
A snapshot will always have a key. Always. And it will be at the location you requested by reference. Whether or not there is data behind that key is irrelevant to the fact that the snapshot will always have a key.
What you need to do is check the data behind that key. Is it null? Then there's no data there. A number? That's data, and it's present.
Use .exists() method:
let ref = firebase.database().ref('players').child(playerId).child('voters');
ref.child(uid).once('value', (snap) => {
console.log(snap.exists()); // This will print true or false
});

$firebaseArray $indexFor() not finding key when given value

I have this firebase:
users: {
userId: {
notifications: {
notificationId: "Notification"
}
}
}
When given "Notification", I'm trying to find its notificationId (which is generated from the push() method) so I can eventually delete it. According to the docs, the $indexFor() method should do this for me. Here's my code:
var ref = new Firebase('https://url.firebaseio.com/');
$scope.dismissNotification = function(notification) {
var notificationRef = ref.child('users/' + $scope.currentUser.id + '/notifications');
var notifications = $firebaseArray(notificationRef);
notifications.$loaded().then(function(data) {
console.log(data);
console.log(data.$indexFor(notification));
}).catch(function(error) {
console.log('Error: ' + error);
});
};
The first log is the correct object with the notification string inside that I'm looking for, but the second log returns -1, when I want it to return the notificationId associated with it.
Not sure what you're trying to accomplish, but this is the simplest way to find the key for a given value:
var notificationRef = ref.child('users/' + $scope.currentUser.id + '/notifications');
var query = notificationRef.orderByValue().equalTo(notification);
query.once('child_added', function(snapshot) {
console.log(snapshot.key());
});

Firebase Displaying Other Users' username except yours Using Presence

Hi I'm new to firebase and was trying out the presence example on firebase everything is working normal. My issue is how do I display the username of others ONLY because everything I cant seem to find the solution for this because
I tried googling for an answer but none of the results are what I'm looking for.
I'm new to Firebase and non-mysql database so I dont know how to do a WHERE Statement on firebase
here is my code:
<body>
<div id="presenceDiv" class="l-demo-container example-base">
</div>
<script>
var name = "<?php echo $uname;?>";
var currentStatus = "★ online";
// Get a reference to the presence data in Firebase.
var userListRef = new Firebase("https://<URL>.firebaseio.com/");
// Generate a reference to a new location for my user with push.
var myUserRef = userListRef.push();
// Get a reference to my own presence status.
var connectedRef = new Firebase("https://<URL>.firebaseio.com//.info/connected");
connectedRef.on("value", function(isOnline) {
if (isOnline.val()) {
// If we lose our internet connection, we want ourselves removed from the list.
myUserRef.onDisconnect().remove();
// Set our initial online status.
setUserStatus("★ online");
}
else {
// We need to catch anytime we are marked as offline and then set the correct status. We
// could be marked as offline 1) on page load or 2) when we lose our internet connection
// temporarily.
setUserStatus(currentStatus);
}
});
// A helper function to let us set our own state.
function setUserStatus(status) {
// Set our status in the list of online users.
currentStatus = status;
myUserRef.set({ name: name, status: status });
}
function getMessageId(snapshot) {
return snapshot.name().replace(/[^a-z0-9\-\_]/gi,'');
}
// Update our GUI to show someone"s online status.
userListRef.on("child_added", function(snapshot) {
var user = snapshot.val();
$("<div/>")
.attr("id", getMessageId(snapshot))
.text(user.name + " is currently " + user.status)
.appendTo("#presenceDiv");
});
// Update our GUI to remove the status of a user who has left.
userListRef.on("child_removed", function(snapshot) {
$("#presenceDiv").children("#" + getMessageId(snapshot))
.remove();
});
// Update our GUI to change a user"s status.
userListRef.on("child_changed", function(snapshot) {
var user = snapshot.val();
$("#presenceDiv").children("#" + getMessageId(snapshot))
.text(user.name + " is currently " + user.status);
});
// Use idle/away/back events created by idle.js to update our status information.
document.onIdle = function () {
setUserStatus("☆ idle");
}
document.onAway = function () {
setUserStatus("☄ away");
}
document.onBack = function (isIdle, isAway) {
setUserStatus("★ online");
}
setIdleTimeout(5000);
setAwayTimeout(10000);
</script>
</body>
</html>
This script keeps on loading my 1st dummy username along the other dummy users that i tried logging on with. The same goes for the other dummy accounts the browser loads their username along with the others.. Whats causing this and how do I solve it? Please help
I'd simply identify and exclude the current user in you on(child_ handlers.
So for example:
// Update our GUI to show someone"s online status.
userListRef.on("child_added", function(snapshot) {
var user = snapshot.val();
if (user.name != name) {
$("<div/>")
.attr("id", getMessageId(snapshot))
.text(user.name + " is currently " + user.status)
.appendTo("#presenceDiv");
}
});

Resources