N.P
N.P

Reputation: 187

Checking if a collection exists in Firestore before creating it

Context: My application currently allows users to create an account, with a username. Upon clicking confirm - to create an account, a check is ran on the username to verify that it does not exist as a document within the usernames collection i.e this allows for only unique usernames within the application.

The usernames were added to a map when the view was created - prior to the user pressing the confirm button (I understand that this is the underlying issue)

public static void getAllNonAvailableUsernames() {
    FirebaseFirestore.getInstance()
            .collection("usernames")
            .get().addOnCompleteListener(task -> {
                 List<DocumentSnapshot> snapshots = task.getResult().getDocuments();
                 for (DocumentSnapshot snap : snapshots) {
                     usedUsernames.put(snap.getId(), snap.get("owner"));
                 }
             });
}

A Problem arises when two users happen to choose the same username to register with. The last request is processed and overrides the owner field within the document, allowing both users to have the same username :

Format of the usernames collection

I'm unsure how to go about solving this issue, since the retrieval of all the documents within the usernames collection might not finish before the validation is occurs.

Upvotes: 1

Views: 2333

Answers (1)

Gil Gilbert
Gil Gilbert

Reputation: 7870

If you must have unique usernames for your users, the only way to do this correctly is with a transaction. Within your transaction, read the specific username you're trying to register then:

  • If the username exists: ask the user for a different username
  • Otherwise set the user record up.

The transaction guarantees that both operations happen atomically.

Note that Firestore transactions only work while online. If you attempt to run a transaction without a network connection it will fail after a few attempts. In this case you'll need to prompt your user to register while they have a network connection.

Upvotes: 1

Related Questions