0
votes

I'm new with firebase cloud function, and have some trouble to get() et set() data from firestore documents within a firebase function.

Here what I try to do within a firebase function :

  1. Access the data of the new document "doc1" when its created in firestore;
  2. Access the value associated with the "user" field of "doc1";
  3. This value is of type "reference", i.e. a path pointing to another document in another firestore collection "col2/doc2"
  4. Use this path to access the second document "doc2" and retrieve two new values belonging to this second document to add it to the first document "doc1";
  5. Final goal is to add the values belonging to the fields "name" and "city" of "doc2" to "doc1" ;

Here what I try up to now, I'm sure I have few problems with syntax and use of then() chain, but the main idea is there :

exports.addDataFromDoc2ToDoc1 = functions.firestore
  .document('col1/{doc1Id}')
  .onCreate((change, context) => {
    const doc1Id = context.params.doc1Id
    const doc1 = change.data()
    const refToDoc2 = doc1.refField

    const doc2Data = refToDoc2.get()
      .then(function (documentSnapshot) {
        if (documentSnapshot.exists) {
          doc2Data = documentSnapshot.data()
          return doc2Data
        }
      })

    const doc1Name = doc2Data.doc1Name
    const doc1City = doc2Data.doc1City

    db.collection('col1')
      .doc(doc1Id)
      .set({
        name: doc1Name,
        city: doc1City
      });
  })

I start from firebase documentation : https://firebase.google.com/docs/functions/firestore-events

const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();

exports.writeToFirestore = functions.firestore
  .document('some/doc')
  .onWrite((change, context) => {
    db.doc('some/otherdoc').set({ ... });
  });

It would be appreciated if someone could help me with this task, and how I can restructure my algorithm to be more efficient maybe?

Thank you very much for your help and your time!

1

1 Answers

0
votes

Since the field is of type Reference, you need to use the path property of the DocumentReference object, as follows:

exports.writeToFirestore = functions.firestore
    .document('col1/{doc1Id}')
    .onCreate((snap, context) => {

        const newValue = snap.data();
        const refToDoc2 = newValue.refField;

        return db.doc(refToDoc2.path).get()
            .then((doc) => {
                if (doc.exists) {
                    const name = doc.data().name;
                    const city = doc.data().city;
                    return snap.ref.update({ name, city })
                } else {
                    throw new Error('No document corresponding to the Reference!')
                }
            })
            .catch(error => {
                console.log(error);
                return null;
            });

    });

In addition, note how we chain the promises returned by the asynchronous Firestore methods and, very important, how we return this promise chain.

Also note that we use the update() method, instead of the set() one.