How to update document in firebase cloud function

こ雲淡風輕ζ 提交于 2021-02-08 10:35:19

问题


In my cloud function I want to update my document from 'dashboard' collection when a new student added to 'students' collection.

const getActiveStudents = () => {
return db.collection('/students/').where('status', '==', true).get().then(
    snapshot => {
        let studentsCount = snapshot.docs.length;
        db.collection('/dashboard/').where('type', '==', 'students').get().then(
            result => {
                if (result.docs.length === 0) {
                    db.collection('dashboard').add({
                        count: studentsCount,
                        type: 'students',
                        label: 'Active students'
                    });
                }else {
                    result.docs[0].ref.update({
                        count: studentsCount,
                        type: 'students',
                        label: 'Active students'
                    });
                }
                return result;
            }
        ).catch(error => {
            console.log(error);
        });
        return snapshot;
    }
).catch(error => {
    console.log(error);
})
}

exports.onChangesInStudents = functions.firestore.document('/students/{studentId}').onWrite(event => {
    getActiveStudents();
    return;
});

When I add a new student, instead of updating document it adds a new document to my 'dashboard' collection. How should I organize my code in order to properly update the quantity of students.


回答1:


as @Doug mentioned, iterating over the entire collection is too heavy. instead you can stream the query results and iterate over keys, using query.stream().

to access and update a single field in a document, first retrieve the document by its ID with doc(), then use update() while specifying the field.

here's an example of implementation based on your scenario.

package.json

{
  "dependencies": {
    "firebase-admin": "^6.5.1",
    "firebase-functions": "^2.1.0"
  }
}

index.js

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

const studentsRef = admin.firestore().collection('students');
const dashboardRef = admin.firestore().collection('dashboard');

exports.addStudent = functions.firestore
  .document('students/{studentId}')
  .onCreate((snap, context) => {
    var newStudent = snap.data();
    console.log('New student in collection: ', newStudent);

    var activeCount = 0;
    studentsRef.where('status', '==', true).select().stream()
      .on('data', () => {
        ++activeCount;     
      }).on('end', () => { 
        dashboardRef.where('type', '==', 'students').get()
          .then(querySnap => {
            if (querySnap.docs[0].data().count == activeCount){
              console.log('No new active student: ', querySnap.docs[0].data());
            } else {
                console.log('New active count: ', activeCount);
                console.log('Student Dashboard before update: ', querySnap.docs[0].id, '=>', querySnap.docs[0].data());
                dashboardRef.doc(querySnap.docs[0].id).update({
                  count: activeCount
                });
                console.log('Active student count updated: ', querySnap.docs[0].data().count, '=>', activeCount);
              };
            });
        });
  return null
  });

gcloud

gcloud functions deploy addStudent \
  --runtime nodejs8 \
  --trigger-event providers/cloud.firestore/eventTypes/document.create \
  --trigger-resource "projects/[PROJECT_ID]/databases/(default)/documents/students/{studentId}"



回答2:


When a function is triggered, you might want to get data from a document that was updated, or get the data prior to update.

You can get the prior data by using change.before.data(), which contains the document snapshot before the update.

Similarly, change.after.data() contains the document snapshot state after the update.

Node.js

exports.updateUser = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
    // Get an object representing the current document
    const newValue = change.after.data();

    // ...or the previous value before this update
    const previousValue = change.before.data();

    //...therefore update the document as.
    admin.firestore().collection('user').doc(docId).update(snapshot.after.data());

});

Reference:- https://firebase.google.com/docs/functions/firestore-events



来源:https://stackoverflow.com/questions/54172490/how-to-update-document-in-firebase-cloud-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!