Michel
Michel

Reputation: 11753

Connecting two promises in a Firebase web app

I am using a Realtime Database to handle some data in a Firebase web app. In the code hereafter, I want to insert a record in the DB only if fieldOne and fieldTwo aren't going to be duplicated.

dbReference.orderByChild("fieldOne").equalTo(fieldOneVal).once('value')
.then(function(snapshot) {
  if (snapshot.exists()) {
    alert('This fieldOne has already been used.')
    reject();
  }
}).then( // What is the correct way to connect this line and the following ??
dbReference.orderByChild("fieldTwo").equalTo(fieldTwoVal).once('value')
.then(function(snapshot) {
  if (snapshot.exists()) {
    alert('This NAME has already been used.')
    reject();
  }

  // All is now OK.
  .... do the final things here .....
}).catch(function(error) {
  // An error happened.
  alert('This record cannot be inserted.')
});

At this point, I am able to tweak the code to make things work the way I wish. But my issue is that I am not doing things the proper way (I know that due to some messages I can see in the console). The comment in my code shows where I need to know the correct way to connect the two parts. What is the .... the following ??

For information the DB looks like this:

MyList
  + -M93j....443cxYYDSN
      fieldOne: "asdc..."
      fieldTwo: "Gkk...."
  + -M94j.........OZS6FL
      fieldOne: "afc..."
      fieldTwo: "SDFSk...."

Upvotes: 0

Views: 52

Answers (2)

Renaud Tarnec
Renaud Tarnec

Reputation: 83058

The following Promises chaining combined with errors throwing should do the trick.

  dbReference
    .orderByChild('fieldOne')
    .equalTo(fieldOneVal)
    .once('value')
    .then(function (snapshot) {
      if (snapshot.exists()) {
        throw new Error('fieldOneExists');
      }
      return dbReference
        .orderByChild('fieldTwo')
        .equalTo(fieldTwoVal)
        .once('value');
    })
    .then(function (snapshot) {
      if (snapshot.exists()) {
        throw new Error('fieldTwoExists');
      }

      // All is now OK.
      //.... do the final things here .....
    })
    .catch(function (error) {
      if (
        error.message === 'fieldOneExists' ||
        error.message === 'fieldTwoExists'
      ) {
        console.log('This record cannot be inserted');
      } else {
        console.log('other error');
      }
    });

However, it would probably be better to use a Transaction for checking the existence of the two values for the fieldOne and fieldTwo fields.

The problem is that the Realtime Database transactions don't work with queries: you need to exactly know the location of the data to be modified (or to be checked for existence/non-existence). So you would need to adapt your data model if it appears that you really need a transaction (which depends on your exact global requirements).

For example you could create database nodes with the concatenation of the values of fieldOne and fieldTwo values and check the existence of such a node in a Transaction. But, again, the feasibility of this approach depends on your exact global requirements, which we don't know.

Upvotes: 1

Piyush Garg
Piyush Garg

Reputation: 163

Try the hasChild() method.

if(snapshot.hasChild('name') {
   // ... do stuff !
}

Or,

create a new node in your firebase real-time db named as usernames and add each username in this list. In future before inserting a new username check if it's present in this list

Upvotes: 0

Related Questions