Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a new field in firestore using cloud functions?

I am a newbie in cloud functions. I want to create a new field counter whenever a document is created.

I tried the following codes:

exports.createCounter = functions.firestore.document('users/{userId}').onCreate((snap, 
 context) => {
  console.log('onCreate created');

      return snap.data.ref.set({counter: 0}, {merge: true})
            .then(() => {
               console.log("Count is created! "+userId);
             })
            .catch((error) => {
                console.error("Counter Error writing document: ", error);
             });
    });

and using firebase-admin:

exports.createCounter = functions.firestore.document('users/{userId}').onCreate((snap, context) => {
  const id = context.params.userId;
  console.log('onCreate created');
  return admin.firestore().collection('users')
  .doc(id).set({counter: 0}, {merge: true})
  .then(() => {
    console.log("Document successfully written! "+id);
  })
  .catch((error) => {
      console.error("Error writing document: ", error);
  });
});

But both are not triggered when a new document is created.

UPDATE

At first, I create users/userId/collection/doc. When it is created, I want to add a counter field into users/userId

like image 431
Marat Avatar asked Sep 17 '25 13:09

Marat


1 Answers

Update following your comment

You can add a field to the users/userId document when you create a doc under the users/userId/theCollection collection by modifying the code of the second solution presented below.

Just trigger at the level of the subcollection, get the parent document id through the context object and build its DocumentReferencebased on this id, as follows:

exports.createCounter = functions.firestore.document('users/{userId}/theCollection/{docId}').onCreate((snap,
    context) => {

    const id = context.params.userId;

    return admin.firestore().collection('users')
        .doc(id).set({ counter: 0 }, { merge: true })
        .then(() => {
            console.log("Count is created! " + userId);
            return null;
        })
        .catch((error) => {
            console.error("Counter Error writing document: ", error);
            return null;
        });
});

Initial answer

The following should do the trick:

exports.createCounter = functions.firestore.document('users/{userId}').onCreate((snap, 
 context) => {
      console.log('onCreate created');

      const docRef = snap.ref;

      return docRef.set({counter: 0}, {merge: true})
          .then(() => {
               console.log("Count is created! "+userId);
               return null;
           })
          .catch((error) => {
               console.error("Counter Error writing document: ", error);
               return null;
           });
    });

Note that instead of doing snap.data.ref to get the DocumentReference you have to do snap.ref. As a matter of fact, snap is a DocumentSnapshot and you need to use its ref property.


Your second code snippet should normally work, but you need to return a value in the then() and in the catch() to indicate to the Cloud Function platform that the work of the function is complete. Note that you need to do the same thing for the above code. I would suggest you watch the 3 videos about "JavaScript Promises" from the Firebase video series: https://firebase.google.com/docs/functions/video-series/ which explain this key point.

exports.createCounter = functions.firestore.document('users/{userId}').onCreate((snap, context) => {
  const id = context.params.userId;
  console.log('onCreate created');
  return admin.firestore().collection('users')
  .doc(id).set({counter: 0}, {merge: true})
  .then(() => {
    console.log("Document successfully written! "+id);
    return null;
  })
  .catch((error) => {
      console.error("Error writing document: ", error);
      return null;
  });
});
like image 198
Renaud Tarnec Avatar answered Sep 20 '25 03:09

Renaud Tarnec