如何在Firebase Cloud功能中更新文档

时间:2019-01-13 19:36:32

标签: firebase google-cloud-firestore google-cloud-functions

在我的云功能中,当新学生添加到“学生”集合中时,我想从“仪表盘”集合中更新文档。

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

当我添加一个新学生时,不是更新文档,而是将一个新文档添加到“仪表盘”集合中。 我应该如何组织我的代码,以便正确地更新学生数量。

enter image description here

2 个答案:

答案 0 :(得分:1)

就像@Doug提到的那样,遍历整个集合太重了。相反,您可以使用query.stream()来流式传输查询结果并遍历键。

要访问和更新文档中的单个字段,请先使用doc()通过其ID检索文档,然后在指定字段时使用update()

这是根据您的情况实现的示例。

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

答案 1 :(得分:0)

触发功能时,您可能希望从已更新的文档中获取数据,或者在更新之前获取数据。

您可以使用change.before.data()获得先前的数据,该文件包含更新之前的文档快照。

类似地,change.after.data()包含更新后的文档快照状态。

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

});

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