如何将数据推送到 Firestore 文档?

How to push data to firestore document?

基本上我想要的是,如果文档不存在则创建一个新文档(现在可以正常工作)但如果文档确实存在,则将新对象推送到现有数组。

我能够从文档中获取数据并 console.log 它们,但不知道如何将新数据推送到现有文档。

我的 FB 结构是这样的:

favorites
  someUserID
    Videos [ 
      0: {
      name: SomeName
      url: SomeUrl
      },

      /* I would like to push new objects like this: */

      1: {
      name: data.name
      url: data.url
      },
    ]

这是我当前的代码:

const { user } = UserAuth();
const UserID = user.uid;
const favoritesRef = doc(db, "favorites", UserID);

const test = async (data) => {
    try {
        await runTransaction(db, async (transaction) => {
          const sfDoc = await transaction.get(favoritesRef);

          if (!sfDoc.exists()) {
            setDoc(favoritesRef, {
                Videos: [{name: data.name}]    
            });
          }

          /* I got my document content here */

          const newFavorites = await getDoc(favoritesRef);
          console.log("Document data:", newFavorites.data());
         
          /* And would like to push new Data here */
          transaction.update(favoritesRef, { name: data.name});
        });
        console.log("Transaction successfully committed!");
    } catch (e) {
        console.log("Transaction failed: ", e);
    }
}

不确定这是否有帮助,但我通常做的是:

我将每个登录的用户添加到一个数组中。

 const snapshot = await getDoc(doc(db, "allUsers", "list"));
 const currentUsers = snapshot.data().users;

 await setDoc(doc(db, "allUsers", "list"), {
        users: [...currentUsers, { name, uid: userId, avatar: photo }],
      });

我首先获取列表中存在的项目,然后创建一个新项目,其中包含之前的所有项目和我正在添加的项目。 currentUsers 是那个 caso 中的当前列表。也许你应该试试这个而不是 Videos: [{name: data.name}]

setDoc(favoritesRef, {
                Videos: [...currentVideos, {name: data.name}]    
                })

要更新数组,Firestore 现在有一个功能,让您 update an array 无需再次编写代码:

Update elements in an array

If your document contains an array field, you can use arrayUnion() and arrayRemove() to add and remove elements. arrayUnion() adds elements to an array but only elements not already present. arrayRemove() removes all instances of each given element.

import { doc, updateDoc, arrayUnion, arrayRemove } from "firebase/firestore";

const washingtonRef = doc(db, "cities", "DC");

// Atomically add a new region to the "regions" array field.
await updateDoc(washingtonRef, {
    regions: arrayUnion("greater_virginia")
});

// Atomically remove a region from the "regions" array field.
await updateDoc(washingtonRef, {
    regions: arrayRemove("east_coast")
});

我是这样想的:

const { user } = UserAuth();
const UserID = user.uid
const favoritesRef = doc(db, "favorites", UserID)

const test = async (data) => {
    try {
        await runTransaction(db, async (transaction) => {
          const sfDoc = await transaction.get(favoritesRef);
          if (!sfDoc.exists()) {
            await setDoc(favoritesRef, {
                favs: [
                    {
                    name: data.name, 
                    ytb: data.ytb, 
                    url: data.url
                }]})
          }
          const doesExists = sfDoc.data().favs.some((fav) => fav.name === data.name)
          console.log(doesExists)
          
          if (doesExists === true)
          
          {
            console.log("AlreadyExist")
          }

          else {
      
          const currentData = sfDoc.data().favs
          
          transaction.update(favoritesRef, {
            favs: [...currentData,
                {
                name: data.name, 
                ytb: data.ytb, 
                url: data.url
            }]}
        )}
        });
        console.log("Transaction successfully committed!");
      } catch (e) {
        console.log("Transaction failed: ", e);
      }
      
}