简体   繁体   中英

Trouble batch setting a document field by docId in Firestore

I have been using firebase (firestore) for a while but I'm a little stuck and was wondering if anyone can think of a solution.

On the firestore DB I have a single collection of users, each user has an email address and several other fields. In this instance I am checking if a user email exists and if it does, I want to create a list field for that particular user with a listUid. I am referencing the users by email, grabbing the docId for those users and then trying to set a list field for each of them.

I am not getting any error's from firestore, it's simply not updating in the DB for some reason and I can't figure out where I am going wrong. Thanks in advance

export const addListUidToExistingUserList = (
  { firestore },
  emailArray,
  listUid
) => {
  return async () => {
    let docIds = [];

    emailArray.forEach((emailAddress) => {
      //find users by email (works)
      const query = db
        .collection("users")
        .where("email", "==", emailAddress);

      //get docId's for user with matching email (works)
      query.get().then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          docIds.push(doc.id);
        });
      });

      //add a new list with corresponding listUid (does not work)
      docIds.forEach((id) => {
        let userRef = db.collection("users").doc(id);
        batch.set(userRef, { lists: [{ listUid }] });
      });
    });
    return await batch.commit();
  };
};

You are running into this issue because your docIds array is always empty at the time you call docIds.forEach .

That's because query.get().then runs asynchronously, and so docIds.forEach is not waiting for it to complete.

You could either:

  • await query.get().then ; or
  • Add the docIds.forEach function INSIDE the then callback of query.get .

Here are your possible fixes:

  1. await query.get().then
//get docId's for user with matching email (works)
await query.get().then((querySnapshot) => {
  querySnapshot.forEach((doc) => {
    docIds.push(doc.id);
  });
});

OR:

  1. docIds.forEach inside then
//get docId's for user with matching email (works)
query.get().then((querySnapshot) => {
  querySnapshot.forEach((doc) => {
    docIds.push(doc.id);
  });

  docIds.forEach((id) => {
    let userRef = db.collection("users").doc(id);
    batch.set(userRef, { lists: [{ listUid }] });
  });
});

Note: Of course, you could also add batch.set directly into your first iteration of querySnapshot.docs.forEach to prevent an unnecessary iteration.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM