Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a document only if it doesn't exist in Firebase Firestore

What I am trying to achieve is very simple. I need to create a user entry in the database only if it doesn't exist.

The app flow:

  1. Create a user with Firebase Auth (obtain UID)
  2. Create a user document in the database using UID as the key

The client code (create operation):

this.db.doc('users/' + uid).set({username: Santa})

The firestore rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{uid} {
      allow create: if 
        request.auth != null && 
        request.auth.uid == uid && 
        !exists(/databases/$(database)/documents/users/$(uid));
      allow update: if request.auth != null && request.auth.uid == uid; 
    }
  }
} 

Additional info:

As you may already know the code doesn't work. Everytime I run the client-side code the current user is completely replaced with a new document. However, if I delete the following line from the rules everything works as expected:

allow update: if request.auth != null && request.auth.uid == uid;

But now the question arises, how do I secure data inside user document from unauthorised modifications? Any advice?

like image 680
manidos Avatar asked Oct 23 '17 11:10

manidos


1 Answers

Use logic in your code, but not in rules. Add addOnCompleteListener to user collection and after get the result do some actions.

getUsers.document(userUID).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> doc) {
     if(!doc.getResult().exists()){
        //add new user
    }
}                       

}

Rules:

match /UsersProfile/{document=**} {
  allow read, write: if request.auth != null;
}
like image 92
Ivan Vovk Avatar answered Oct 20 '22 12:10

Ivan Vovk