1

I am trying to copy a collection of documents from one collection to another collection by using a cloud Firestore function. I'm modeling my code off of Cloud Functions: How to copy Firestore Collection to a new document?.

I have the following code, however, I'm getting the following errors when I try to deploy to Firestore.

-Forbidden 'var' keyword, use 'let' or 'const' instead -Promises must be handled appropriately -'promise' is declared but its value is never read.

I'm assuming this is an issue with the TS syntax potentially being different than JS.

    exports.addNewFollowerPost = functions.firestore
    .document(`followers/{userID}/userFollowers/{newFollowerID}`)
    .onCreate(async (snap, context) => {
        const newFollowerID: string = context.params.newFollowerID;
        const userID: string = context.params.userID;

        admin.firestore().collection(`profile_posts`).doc(newFollowerID).collection(`posts`).get().then(query => {
            query.forEach (function(doc){
                const promise = admin.firestore().collection(`fake_posts`).doc(doc.data().barcode).set(doc.data());
            });
        });

    });

I'm still pretty new to cloud functions and TS/JS. Appreciate any advice!


UPDATED CODE

I took the advice and created a list of promises and called Promise.all on it:

exports.addNewFollowerPost = functions.firestore
    .document(`following/{userID}/userFollowers/{newFollowerID}`)
    .onCreate(async (snap, context) => {
        const newFollowerID: string = context.params.newFollowerID;
        const userID: string = context.params.userID;

        try {
            const promises = []
            const newFollowerPostQuerySnapshot = await admin.firestore().collection(`profile_posts`).doc(newFollowerID).collection(`posts`).get()
            const followerPosts = newFollowerPostQuerySnapshot.docs
            followerPosts.forEach(post => {
                const p = admin.firestore().collection(`fake_posts`).doc(post.id).set(post);
                promises.push(p)
            })
            const snapshots = await Promise.all(promises);
        }
        catch (error) {
            console.log(error)
        }
    })

I am able to deploy successfully, but then get the following error: "Value for argument "data" is not a valid Firestore document. Couldn't serialize object of type "QueryDocumentSnapshot". Firestore doesn't support JavaScript objects with custom prototypes"

Am I unable to pass a DocumentSnapshot via the set method?

PJQuakJag
  • 1,067
  • 4
  • 16
  • 35
  • 1
    You're not handling the return value of your Firestore `set()` API calls. I would expect the `cont promise` to be added to a list, followed by a call to `Promise.all()`. Spend some time learning about async programming in JS. This might be a good starting point: https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html – Hiranya Jayathilaka Apr 15 '19 at 18:06
  • @HiranyaJayathilaka Thanks for the help. Edited the post based on your advice and additional reading/videos. Would love any context you might have for edited issue? Can I get a DocumentSnapshot from a promise and then pass it via the set method? – PJQuakJag Apr 16 '19 at 15:17
  • You cannot pass a snapshot to `set()`. You should do `set(post.data())` in your code. – Hiranya Jayathilaka Apr 16 '19 at 18:13
  • This worked! Appreciate the help! – PJQuakJag Apr 17 '19 at 02:28

0 Answers0