Firebase update or set - javascript

After adding a post about a person to a Firebase database, I want to add the reference to the new post to the person. However the person may or may not already exist.
I have:
var ref = new Firebase("https://mydatabase.firebaseio.com/");
var _person = document.getElementById("Person").value;
var _remark = document.getElementById("Remark").value;
var postsRef = ref.child("remarks");
var newPostRef = postsRef.push({
person: _person,
remark: _remark
});
var postID = newPostRef.key();
var personRef = ref.child("person");
personRef.update({
_person: postID
});
However that creates a node called _person in child person instead of the value of the _person variable. Using set() would overwrite an existing person.
Example:
First a node remarks/-JlkbxAKpQs50W7r84gf is created with child node person/123456
After that I want to create a node person/123456 (only if it doesn't already exist) and than add a child node remark/-JlkbxAKpQs50W7r84gf to it. The post-id is automatically generated (Firebase) but the person's id is to be taken from a html form.
How do I do that?

Depending on how your data is structured, before you update, you may be able to get a reference to the person you want.
So, if your data looks something like this:
{
"remarks" : {
...
},
"person" : {
"123456" : {
"name" : "foo",
...
"blah" : "bar"
},
...
}
}
And document.getElementById("Person").value gives you 123456, you can get the reference like:
var personRef = ref.child("person").child(_person);
Then you want to see if it exists, and if it does, update it:
personRef.once('value', function(snapshot) {
if( snapshot.val() === null ) {
/* does not exist */
} else {
snapshot.ref.update({"postID": postID});
}
});

Related

Create index on already existing objectStore

As an example on basic setup one index is created.
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by name', 'name', { unique: false });
};
Question:
Is it possible to create/append more indexes to the same objectStore on the future versionupdate? Since if I try:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.createObjectStore('name', { keyPath: 'id' });
store.createIndex('by newName', 'newName', { unique: false });
};
It throws an error that current objectStore does already exist. An if I try to create store reference using transaction:
db.onupgradeneeded = function(event) {
var db = event.target.result;
var store = db.transaction('name', 'readwrite').objectStore('name');
store.createIndex('by newName', 'newName', { unique: false });
};
It throws that version change transaction is currently running
Yes it is possible. It can be a bit confusing at first. You want to get the existing object store via the implicit transaction created for you within onupgradeneeded. This is a transaction of type versionchange which is basically like a readwrite transaction but specific to the onupgradeneeded handler function.
Something like this:
var request = indexedDB.open(name, oldVersionPlusOne);
request.onupgradeneeded = myOnUpgradeNeeded;
function myOnUpgradeNeeded(event) {
// Get a reference to the request related to this event
// #type IDBOpenRequest (a specialized type of IDBRequest)
var request = event.target;
// Get a reference to the IDBDatabase object for this request
// #type IDBDatabase
var db = request.result;
// Get a reference to the implicit transaction for this request
// #type IDBTransaction
var txn = request.transaction;
// Now, get a reference to the existing object store
// #type IDBObjectStore
var store = txn.objectStore('myStore');
// Now, optionally inspect index names, or create a new index
console.log('existing index names in store', store.indexNames);
// Add a new index to the existing object store
store.createIndex(...);
}
You also will want to take care to increment the version so as to guarantee the onupgradeneeded handler function is called, and to represent that your schema (basically the set of tables and indices and properties of things) has changed in the new version.
You will also need to rewrite the function so that you only create or make changes based on the version. You can use event.oldVersion to help with this, or things like db.objectStoreNames.contains.
Something like this:
function myOnUpgradeNeeded(event) {
var is_new_db = isNaN(event.oldVersion) || event.oldVersion === 0;
if(is_new_db) {
var db = event.target.result;
var store = db.createObjectStore(...);
store.createIndex('my-initial-index');
// Now that you decided you want a second index, you also need
// to do this for brand new databases
store.createIndex('my-second-new-index');
}
// But if the database already exists, we are not creating things,
// instead we are modifying the existing things to get into the
// new state of things we want
var is_old_db_not_yet_current_version = !isNaN(event.oldVersion) && event.oldVersion < 2;
if(is_old_db_not_yet_current_version) {
var txn = event.target.transaction;
var store = txn.objectStore('store');
store.createIndex('my-second-new-index');
}
}
Pay close attention to the fact that I used event.target.transaction instead of db.transaction(...). These are not at all the same thing. One references an existing transaction, and one creates a new one.
Finally, and in addition, a personal rule of mine and not a formal coding requirement, you should never be using db.transaction() from within onupgradeneeded. Stick to modifying the schema when doing upgrades, and do all data changes outside of it.

How do I use $save() in Firebase' Angular-Fire to Update Object Property Values

I have the code below:
var FBref = new Firebase('https://employees.firebaseio.com/');
var peopleObject = $firebaseArray(FBref);
var person = {
"name":"John",
"age":"20",
"phone":"123-123-123"
};
peopleObject.$add(person);
I use the code above to add new records of employees successfully.
I need to update the John's phone number to 111-111-111. But the code below doesn't work.
var person = {
"name":"John",
"age":"20",
"phone":"111-111-111" //New phone number
};
peopleObject.$save(person);
Someone advice
Currently you are trying to save whole object, which wouldn't work.
Retrieve old record first by getting record from db first & then update that record. Thereafter save that object using $save method.
//if update action is happening is similar session you can get unique by below code
var someRecordKey;
peopleObject.$add(person).then(function(ref) {
//get record id of new person
someRecordKey = ref.key();
});
// get record by unique key
var person = peopleObject.$getRecord(someRecordKey);
// change a message and save it
item.phone = "111-111-111";
peopleObject.$save(person).then(function() {
// data has been saved to our database
});

Order by child and retrieve other child value

I have the following data set:
person-base
{
-K771quXhYWTo-F8oei9
{
person: "Sam"
value: 2
}
-K771uFngeQ6j0rvDhN_
{
person: "Joe"
value: 1
}
}
I am trying to retrieve the value of one of these keys based on it's person child.
I created a query that I'm using to point to the person value that matches the value of my personName variable (in this case "Sam") and so far, based on what I see in the console, it correctly retrieves the respective key and it's children.
My code:
var personRef = new Firebase("https://person-base.firebaseio.com/");
var personName = "Sam";
var query = personRef.orderByChild('person').equalTo(personName);
query.on('value', function(snapshot) {
console.log(snapshot.val());
console.log(snapshot.val().key()); // error
});
My plan was to retrieve the parent key (generated by .push) that contains my person value and then to run something like the code I have below in order to retrieve value
personRef.child(key).on('value', function(childSnapshot) {
var obj = childSnapshot.val();
console.log(obj.value);
});
However I am unable to retrieve the parent with my query.
My fiddle for further reference: https://jsfiddle.net/y20Lucyx/1/
When you execute a query, the result is always a snapshot of all child nodes that match that query. Even though in your case there is only one matching child, you still need to handle the child with a loop:
query.on('value', function(snapshot) {
snapshot.forEach(function(sam) {
console.log(sam.val());
console.log(sam.key());
});
});

FireBase - angularfire setting object key as variable

I am using firebase(angularfire) in my angularjs app to store and process my message system but can't seem to figure out how to replicate the example data from the firebase docs
// room members are easily accessible (or restricted)
// we also store these by room ID
"members": {
// we'll talk about indices like this below
"one": {
"mchen": true,
"hmadi": true
}
}
Here the members.one contains the user name as a key and I am trying to do this for my data as well but can't seem to figure out a solution.
The members portion of my firebase data is like so:
members { one: { } }
I have two variables set in the $scope.
user_name = kep; //person chatting with name
sender_name = pek; //current user name
So I want to use the set function to insert data into members.one or in this case members.user_name + ':' + sender_name but where I am having trouble is how to actually insert the data without creating a parent object.
ref.child('members').child(user_name + ':' + sender_name).set({
user_name: true, sender_name: true
});
The problem arises when I try to pass user_name and sender_name into the set() function below is the result it gets.
members { "kep:pek": { user_name: true, sender_name: true }}
where as I want it to be:
members { "kep:pek": { kep: true, pek: true }}
If I put user_name and sender_name into an object and then run the set() function with the object passed it will create the following structure which is not what I am looking for:
members { "kep:pek": { newObject: { kep: true, pek: true }}}
Firebase team member here.
The Firebase Database is a just a JSON document.
So let's say you want to structure your data this way:
{
"members" : {
"kep:pek" : {
"kep" : true,
"pek" : true
}
}
}
A custom key is created by using the .child() method, or by creating a key in the JavaScript Object.
JSBin Demo
var rootRef = new Firebase('<my-firebase-app>');
var membersRef = rootRef.child('members');
var user_name = 'kep';
var sender_name = 'pek';
// child object to store custom keys
var objectToSave = {};
// set keys in [] syntax
objectToSave[user_name] = true;
objectToSave[sender_name] = true;
// use .child() with a formatted string to save the object
membersRef.child(user_name + ':' + sender_name).set(objectToSave);

How to add a property (property name is variable) to object via MongoDB driver (node.js)

The structure of my document in collection is this.
{
"_id" : ObjectId("54e74de2950fd3a4e5f0a37a"),
"userName": "Any_user",
"ratings": {
"rating1" : [ ],
"big_rating" : [ ]
}
}
In MongoDB client (mongo.exe) the adding i need looks like this
db.userContent.update({userName: "NXTaar"}, {$set: {"ratings.variable_name": []}})
I need the function for the MongoDB node.js driver
And yes, i know the "property name as string" thing there i can pass the variable to the property name. Here is what i tried to make:
var rating = {};
var title = 'some_string';
ratings[title] = [];
usercontent.update({userName: "some_user"}, {$set: ratings}, function (err, doc) {...})
this line adds a new object to the document with a name of property
usercontent.update({userName: "some_user"}, {$set: {ratings: ratings}}, function (err, doc) {...})
and this one does exactly what i need, but each time it runs, it rewrites current property with a new one(yes, i know, it because of $set parameter which changes selected object with the thing that you've passed to it)
I need a function which adds a property to object with a name given through variable
Like so:
var t = "property_name"
var field_name = "ratings." + t
var update = { "$set" : { } }
update["$set"][field_qname] = []
db.usercontent.update({ "userName" : "some_user" }, update)
Construct the proper dot notation field name and then the proper $set update expression, then pass that to the update function.

Categories

Resources