简体   繁体   中英

react Firestore query nested collection where field then update, or add new doc

I'm currently ripping my hair out trying to query a nested collection in my Firestore db.

my db is set up as follows:

  users (collection)
    - username
    - displayName
    - ratedItems (collection)
            - itemId
            - timestamp
            - likedItem

I want to be able to add/update the rated item in the ratedItems collection for a specific user but I seem to be hitting 2 problems:

  1. I assume the query is incorrect as if(querySnapshot.empty) always returns false even if there are no matching items (matching the itemId) in the ratedItems collection, so it always attempts to add a new item which results in duplicate entries in the collection.

  2. if I force the code to bypass the conditional it throws an error when it attempts to update the existing item:

Expected type 'mc', but it was: a custom yc object

My thoughts are I am using the collectionGroup query incorrectly but I haven't found a solution for this yet. Should I even be using collectionGroup at all?? from what I've read, if I understand correctly this will query every ratedItem collection regardless of the user, which isn't what I want

 const rateItem = async (itemId, liked) => {
    try {
      const itemRef = collection(db, 'users', currentUser.uid, 'ratedItems');
      const q = query(
        collectionGroup(db, 'users', currentUser.uid),
        where('itemId', '==', itemId)
      );
      const querySnapshot = await getDocs(q);

      if (querySnapshot.empty) {
        await addDoc(itemRef, {
          itemId: itemId,
          timestamp: serverTimestamp(),
          likedItem: liked,
        });
      } else {
        await updateDoc(itemRef, {
          timestamp: serverTimestamp(),
          likedItem: liked,
        });
      }
    } catch (err) {
      console.log(err.message);
    }
  };

I assume the query is incorrect as if(querySnapshot.empty) always returns false even if there are no matching items (matching the itemId) in the ratedItems collection, so it always attempts to add a new item which results in duplicate entries in the collection.

You used the itemRef for both of addDoc and updateDoc which is not the proper way to do it. You need a correct query syntax in order to update your Firestore document.

if I force the code to bypass the conditional it throws an error when it attempts to update the existing item

You can try the code below to update your nested document:

const updateitemRef = query(
    collection(db, 'users', 'user_item', 'ratedItems'), 
    where('itemId', '==', itemId)
);

const itemSnapshot = await getDocs(updateitemRef);

itemSnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots 
    updateDoc(doc.ref, {
        likedItem: liked,
        timestamp: serverTimestamp()          
    });
});  

For the complete code, you can try the code below:

const rateItem = async (itemId, liked) => {
    try {
        const q = query(
            collectionGroup(db, 'users', currentUser.uid),
            where('itemId', '==', itemId)
        );
        const querySnapshot = await getDocs(q);

        const additemRef = collection(db, 'users', currentUser.uid, 'ratedItems');

        const updateitemRef = query(
            collection(db, 'users', currentUser.uid, 'ratedItems'), 
            where('itemId', '==', itemId)
        );
        const itemSnapshot = await getDocs(updateitemRef);

        if (querySnapshot.empty) {
            await addDoc(additemRef, {
                itemId: itemId,
                likedItem: liked,
                timestamp: serverTimestamp()
            });
        } else {
            itemSnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots 
                updateDoc(doc.ref, {
                    likedItem: liked,
                    timestamp: serverTimestamp()          
                });
            });      
        }
    } catch (err) {
        console.log(err.message);
    }
};

For more references in creating a query, you can refer to the guides below:

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