Search code examples
javascriptangularfirebasegoogle-cloud-firestoreangularfire2

Check if user exists in Firestore before attempting any further processing


I have written a custom referral script on my website and on occasion users have complained that their referralId is being overwritten, so they lose any points they have built up over a period of time. I want to stop this from occurring by including a check to see if a uid exists before attempting an update.

Is there a way for me to check that the user's uid exists, with a valid referral id before executing this command any further? I think the issue is occurring here:

  processUser(result, firstName, lastName) {
    const referralId = this.utilService.generateRandomString(8);
    this.setUserData(result.user);
    this.setUserDetailData(result.user.uid, firstName, lastName, referralId);
    this.referralService.addUserToWaitlist(referralId);
  }

Is there a way for me to check that this beforehand? My table structure is below:

enter image description here


Solution

  • To check if a document and exists and only write if it doesn't, you'd typically use a transaction. See https://firebase.google.com/docs/firestore/manage-data/transactions#transactions. From there:

    db.runTransaction(function(transaction) {
        // This code may get re-run multiple times if there are conflicts.
        return transaction.get(sfDocRef).then(function(sfDoc) {
            if (!sfDoc.exists) {
                throw "Document does not exist!";
            }
    
            var newPopulation = sfDoc.data().population + 1;
            transaction.update(sfDocRef, { population: newPopulation });
        });
    })
    

    Note that you can also merge the user data with the existing data in the document, to prevent needing a transaction. For example:

    userRef.set({ 
      firstName: firstName, lastName: lastName, referralId: referralId
    }, { merge: true });
    

    I'm not sure if this is good enough for your use-case, but definitely check it out as the code is simpler than for a transaction.