Sahand
Sahand

Reputation: 8370

How to store list of objects for each user in firebase

I'm trying to write an application using firebase. I want to store JSON search objects in searches/ and a reference to each one of them in a table belonging to the user that made the search. Here's my attempt:

  var firebase = require("firebase");
  firebase.initializeApp(firebaseConfig);
  var database = firebase.database();

  /*
  * Inserts a search into the database
  */
  this.addSearchToDB = function(positive, negative, neutral){
    let today = new Date();
    let dateCreated = today.getFullYear()+"-"+(today.getMonth()+1)+"-"+today.getDate();
    var search = {
                "query": searchInput,
                "location": location,
                "until": date,
                "dateCreated": dateCreated,
                "amount": tweetAmount,
                "positive": positive,
                "negative": negative,
                "neutral": neutral
                };
    //setup of path to reference the data
    var searchesRef = database.ref("searches");
    var newSearchKey = searchesRef.push(search).key;

    console.log("newSearchRef key:");
    console.log(newSearchKey);

    let user = firebase.auth().currentUser;
    let uid = user.uid;

    console.log("Curr user id: "+uid);

    let userRef = database.ref("users/"+uid);
    let currUserSearches;
    userRef.once("value").then( (value) => {
      currUserSearches = value;
    });

    console.log("Current user searches");
    console.log(currUserSearches);

    if (currUserSearches === undefined)
      currUserSearches = [];

    currUserSearches.push(newSearchKey);

    userRef.set(currUserSearches).then( () => {
      database.ref("users/"+uid).once("value").then((value)=>{
        console.log(value.val());
      });
    });
  }

On the first insert, this happens:

  1. I get a newSearchKey (logs successfully to console)
  2. I get the user id of the currentUser (logs successfully to console)
  3. currUserSearches is undefined. (logs undefined to console)
  4. In the userRef.set() callback, a list containing newSearchKey is found and printed to the console.

This is all good. It is what I would expect of the first insert. BUT, when I insert again, the exact same procedure repeats itself, meaning that currUserSearches is once again undefined. This is of course wrong. currUserSearches should contain that key that I just inserted. But it seems like it's forgotten what I inserted.

What is going on here, and how can I achieve the behaviour I want?

Upvotes: 1

Views: 356

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83163

This is because all queries (read and write) to the Firebase database are asynchronous. The console.log #3 is executed before the userRef.once("value") returns a result.

You should chain the promises, as follow:

let userRef = database.ref("users/"+uid);
let currUserSearches;

userRef.once("value")
.then( (value) => {
  currUserSearches = value;

  if (currUserSearches === undefined)
        currUserSearches = [];

      currUserSearches.push(newSearchKey);

      return userRef.set(currUserSearches);
})
.then( () => {
  return database.ref("users/"+uid).once("value");  // <- Actually could be userRef.once("value") 

})
.then((value)=>{
    console.log(value.val());
});

Upvotes: 2

Related Questions