Daniel Bílek
Daniel Bílek

Reputation: 85

How to push data to firestore document?

Basically what I want is that if a document doesn't exist then create a new one (it works fine now) but if a document does exist, push a new object to the existing array.

I was able to get data from documents and console.log them, but don't know how to push new ones to the existing document.

My FB structure looks like this:

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

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

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

This is my current code:

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);
    }
}

Upvotes: 0

Views: 940

Answers (3)

Daniel Bílek
Daniel Bílek

Reputation: 85

I just figured it out like this:

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);
      }
      
}

Upvotes: 0

Andres Fiesco Casasola
Andres Fiesco Casasola

Reputation: 801

To update the array Firestore now has a function that allows you to update an array without writing your code again:

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")
});

Upvotes: 1

José Carlos
José Carlos

Reputation: 774

Not sure if this helps but what i usually do is:

I'm adding every user that signs in to an array.

 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 }],
      });

I first get the items that exist in the list, and them i create a new one that has every previous item and the ones i'm adding. The currentUsers is the current list in that caso. Maybe you should try thist instead of Videos: [{name: data.name}]

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

Upvotes: 0

Related Questions