How to update a pushed Fire Base object - firebase

Pushed firebase objects are hidden behind a unique key, making referencing a pushed object difficult unless your using childAdded. And a reference is needed if you want to use update on the object.
{
"ideaCount" : 0,
"ideas" : {
"-KNVuaB6ZaRCLmH0q8ic" : {
"idea" : {
"likes" : 0,
"name" : "test"
}
},
//unique key, every idea will have a new one of these
"-KNVucJEgZxz_N0P8bcv" : {
//want to reference this
"idea" : {
"likes" : 0,
"name" : "jkl"
}
}
}
Is it possible to update that "idea" object without explicitly putting that unique key in the reference?
Can I start the reference after the unique key? From my experience you need to start the reference at the root.
To be more specific, I would like to be able to change the "likes" number up and down on button press and update seemed to be the best way to do it.

To simply answer your question, no. You will need the push key to complete the reference to ideas/some-idea/likes. However, I am assuming your are listing these "ideas" so people can like them in which you will always have the push key available. For example:
JavaScript
var theIdeas= [];
var ref = firebase.database().ref("ideas");
ref.once("value").then(function(snapshot) {
snapshot.forEach(function(childSnapshot) {
// Push key
var key = childSnapshot.key;
// childData will be the actual contents of the child
var childData = childSnapshot.val();
});
theIdeas.push(childData);
}, function(error) {
});
AngularJS
var ref = firebase.database().ref("ideas");
var ideas = $firebaseArray(ref);
<!-- Push key is stored inside $id -->
<div ng-repeat"i in ideas"> {{i.$id}} </div>
Do whatever you wish when you receive that information. The point is that if you have grabbed an "idea" then you do know what the push key is and should be able to use it has part of your reference.
References:
Firebase | key

Related

Flutter/Firebase : I want to update existing values, but new values are being created

I'm working on a flutter project and this is my code :
String vl = store.reference().child("Volunteers/Aadithya").push().key;
vlRef = FirebaseDatabase.instance.reference().child("Volunteers/Aadithya");
vlRef.child(vl).update({
"Contributions": int.parse(count)+1,
}).then((_) {
}).catchError((onError) {
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text(onError)));
});
Contributions is a data record inside Aadithya. I need to update its value alone. But what happens is, a new sub-record is being created inside Aadithya, with contributions being its data type
Please help:
You are adding it to a child with random ID. You don't need the push key. Try this:
vlRef = FirebaseDatabase.instance.reference().child("Volunteers/Aadithya");
vlRef.update({
"Contributions": int.parse(count)+1,
}).then((_) {
}).catchError((onError) {
Scaffold.of(context).showSnackBar(SnackBar(content: Text(onError)));
});
.child(vl) means you are adding another child node with that value.

How do i query a Firebase database for a nested property?

Hi i have a noSql db in firebase.
I want to get the object where userId is 288
i'v tried many combinations but i cant figure out how its done.
This is my code so far :
var refTest= database.ref('conversation')
var query = refTest
.orderByChild('messages');
query.on('value', function(data) {
var a = data.val();
console.log(a.messages.userId);
console.log(data.val());
});
This is a image of my "schema"
I'm obviously a noob when it comes to NoSQL. I do understand SQL
All help is appreciated
You can order/filter on a nested value like this:
var refTest= database.ref('conversation')
var query = refTest.orderByChild('messages/userId').equalTo("288");
query.on('value', function(snapshot) {
snapshot.forEach(function(child) {
console.log(child.key);
console.log(child.val());
});
});
The forEach is needed, since there may be multiple child nodes with messages/userId equal to 288.
The key named "messages" doesn't make sense in your schema. Because if you want to have another message under that conversation, then you wouldn't be able to add it with the same key name and you also couldn't add it under "messages" because it would overwrite the other one. My suggestion is to use the push() method for adding a new message. This way you uniquely identify each message.
Regarding your question, an easy to understand way of parsing your schema is this: you loop through each message of each conversation for finding the messages with userID.
refTest.on('value', function(data) {
var conversations = data.val();
for (conversation in conversations){
for (message in conversation) {
if (message.userId == 288) {
// do whatever you need
// and eventually return something to break the loops
}
}
}
}
Of course, you can adapt it based on your needs

How to update nested object of firebase data in (angularfire2 / Ionic), and also i want to update with given value not with key

I was integrate firebase with ionic3 angularjs, adding data successfully like
var fireData =
{
userid : '1122233',
questionId : '18022',
answerId : '25633',
points : '2'
}
//Add
this.sample.list('paperCode').push(fireData);
Now I want to update like below mentioned image
If you don't know the key, first query the data with the field you know then iterate through the result and get the key. Then you can perform update.
Try
updateFunction(questionId){
this.sample.list('/paperCode', ref => ref.orderByChild('questionId').equalTo(questionId)).snapshotChanges()
.subscribe(actions => {
actions.forEach(action => {
// here you get the key
console.log(action.key);
this.sample.list('/paperCode').update(action.key, { points: 10 });
});
});
}
I hope your question id is unique, otherwise it will override all queried results.
You need to set a path to that object and update the field you would like. In this example...
firebase.database().ref(1710172911409/L5F4BEuePS8qxUqDNoF/questionId).update("NEWQUESTIONID);
If you don't know the unique id of the pushed object, you can query for it. Learn more here

Is a variable for a field name allowed during update in Meteor?

I have been trying to update a collection i have.Problem is,i dont know the field name so am relying on some logic to come up with the field name.
For instance
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {
$set: {
"x" : y
}
});
where x is the field name.
This is my code
var obj = {};
obj[x] = y;
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {$set: {obj}});
I am getting this error
update failed: MongoError: The dotted field 'ersubjects.0.English' in
'obj.ersubjects.0.English' is not valid for storage.
English is a field under ersubjects so i want to update it this way ersubjects.0.English and it works on mongo.
Why is this not working in meteor?.
You can't store documents that have a dot in the key. See this answer for an explanation.
What you can do is use lodash's extremely handy _.set function to create your object with dynamic keys like this:
var obj = {};
var variableKey = 'ersubjects';
_.set(obj, [variableKey, 0, 'English], 'someValue');
Now you can safely store this object to Mongo.

AngularFire extending the service issue

I've been looking at the documentation for Synchronized Arrays https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-extending-the-services and https://www.firebase.com/docs/web/libraries/angular/guide/extending-services.html#section-firebasearray
I'm using Firebase version 2.2.7 and AngularFire version 1.1.2
Using the code below, I'm having trouble recognizing $$removed events.
.factory("ExtendedCourseList", ["$firebaseArray", function($firebaseArray) {
// create a new service based on $firebaseArray
var ExtendedCourseList= $firebaseArray.$extend({
$$added: function(dataSnapshot, prevChild){
var course = dataSnapshot.val();
var course_key = dataSnapshot.key();
console.log("new course");
return course;
},
$$removed: function(snap){
console.log("removed");
return true;
}
});
return function(listRef) {
return new ExtendedCourseList(listRef);
}
}])
.factory("CompanyRefObj", function(CompanyRef) {
//CompanyRef is a constant containing the url string
var ref = new Firebase(CompanyRef);
return ref;
})
.factory('CourseList', function (localstorage,$rootScope,ExtendedCourseList,CompanyRefObj) {
var companyID = localstorage.get("company");
$rootScope.courseList = ExtendedCourseList(CompanyRefObj.child(companyID).child("courses"));
)
If I run this code, only the $$added events will be triggered. To simulate the remove events I use the web-interface at Firebase to display data, where I press the remove button and accept the data being deleted permanently.
Additionally, if I delete the $$removed function, the extended service still won't synchronize when a record is deleted.
If I modify my code to use the $firebaseArray instead of extending the service (as seen above) both add and remove events will be recognized.
.factory('CourseList', function (localstorage,$rootScope,$firebaseArray,CompanyRefObj) {
var companyID = localstorage.get("company");
$rootScope.courseList = $firebaseArray(CompanyRefObj.child(companyID).child("courses"));
)
Finally, are there any bad practices I've missed that can cause some of the extended functions to not work?
Solved
$$added: function(dataSnapshot, prevChild){
var course = dataSnapshot.val();
var course_key = dataSnapshot.key();
//Modified below
course.$id = course_key;
//End of modification
console.log("new course");
return course;
}
After posting about the issue at firebase/angularfire github I received an answer that solved my issue. When $$added got overridden by the code provided, the $firebaseArray also lost its internal record $id.
Adding this line of code: course.$id = course_key; before returning the course, made AngularFire recognize when the record was removed from the server.

Resources