Ripas55
Ripas55

Reputation: 943

why firestore updates the document few minutes after successful cloud function completion?

I am using callable cloud function to update the users username, the function works most of the time, however occasionaly it takes up to 3 minutes to see updated username in the firestore after the function was successfully completed.

Just have 2 questions:

  1. what is the reason behind being so slow at random times?

  2. On the front, I get response "successfully changed username", even though, that's not true since firestore hasn't really updated anything, so because of all this I can't even invalidate my queries.

export const addUsername = functions
  .region("us-central1", "europe-west2")
  .https.onCall(async (data: string, context) => {
    if (context.auth?.uid) {
      // check if a new username is available
      const userId = context.auth.uid;
      const db = getFirestore();
      const batch = db.batch();
      const docRef = db.collection("usernames").doc(data);
      const userPublicRef = db.collection("usersPublic").doc(userId);
      const usersPrivateRef = db.collection("users").doc(userId);
      docRef
        .get()
        .then(async (doc) => {
          if (!doc.exists) {
            // adds new username to usernames, usersPublic, users collections
            batch.set(docRef, {
              uid: userId,
            });
            batch.set(userPublicRef, { username: data }, { merge: true });
            batch.set(usersPrivateRef, { username: data }, { merge: true });
            const oldUsernameSnap = await admin
              .firestore()
              .collection("usernames")
              .where("uid", "==", userId)
              .get();
            // deletes the old username which makes it available for others
            oldUsernameSnap.forEach((doc) => batch.delete(doc.ref));
            batch.commit();
          } else {
            throw new Error("Document already exists");
          }
        })
        .catch(() => {
          throw new Error("Something went wrong");
        });
      return {
        message: "successfully changed the username",
      };
    }
    return {
      message: "not authenticated",
    };
  });

Of course I can just inform users that "changes might take up to 3 minutes" , but thats not what I want to do, I would really appreciate some information about his.

Upvotes: 0

Views: 66

Answers (1)

Dharmaraj
Dharmaraj

Reputation: 50830

You are indeed returning the response before the docRef is fetched. Try adding a return before docRef.get ans then return response after committing the batch.

return docRef.get().then(async (doc) => {
   ...
   await batch.commit()
   return { message: "updated" }
})

Upvotes: 1

Related Questions