【问题标题】:Cloud Function Update Problem in Firestore DatabaseFirestore 数据库中的云函数更新问题
【发布时间】:2019-03-13 21:38:08
【问题描述】:

我正在尝试构建一个 Android 应用程序。在我的 Firestore 数据库中,我有用户集合和计数器集合。在 Counters 集合中,我有 userCounter。我想做的是每当有新用户登录并将其推送到firestore时,userCounter就会增加。

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

exports.addNewUser = 
functions.firestore.document('Users/{userID}').onCreate((event) => {

var db = admin.firestore();
var counterRef = db.collection("Counters");
var temp = counterRef.doc("0").data().userCounter++;

counterRef.doc("0").update(
{
    userCounter: temp
});
});

在这种状态下,这个功能不起作用,我是新手,所以我很感激任何帮助。 提前谢谢

编辑

在实施 Firebaser 和 Pablo Almécija Rodríguez 的答案后,我的代码如下所示。

const Firestore = require('@google-cloud/firestore');
const firestore = new Firestore({
  projectId: process.env.GCP_PROJECT,
});
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();

exports.addNewUser =
functions.firestore.document('Users/{userId}').onCreate((snapShot) => {

  const userCounterRef = db.collection('Counters').doc('Users');

  return db.runTransaction(transaction => {

   const doc = transaction.get(userCounterRef);

    console.log("1");
   const count = doc.data();
    console.log(`5`);
   const updatedCount = count + 1;
    console.log(`6`);
   return transaction.update(userCounterRef, {counter: updatedCount })
  })
});

这是 firebase 控制台日志。问题是

const count = doc.data();
TypeError: doc.data is not a function

Firebase Console Log

【问题讨论】:

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


    【解决方案1】:

    我建议您创建一个名为 counters 的集合,并在其中创建一个名为 users 的文档来处理用户的计数器。这是结构:

    - counters (collection)
      - users (document)
        count: 0 (field)
    

    然后,您应该使用事务对此计数器文档执行更新,以确保您使用最新数据来处理并发(同时创建多个帐户)

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp();
    const db = admin.firestore();
    
    exports.addNewUser = 
    functions.firestore.document('users/{userId}').onCreate((snapShot) => {
    
      const userCounterRef = db.doc('counters/users');
    
      return db.runTransaction(async transaction => {
       const doc = await transaction.get(userCounterRef)
       const { count } = doc.data()
       const updatedCount = count + 1
       return transaction.update(userCounterRef, {count: updatedCount })
      })
    });
    

    https://firebase.google.com/docs/firestore/manage-data/transactions

    编辑:如果您不想处理异步/等待语法,请像这样更新您的事务:

    return db.runTransaction(transaction => {
         return transaction.get(userCounterRef)
         .then(doc => {
             const count = doc.data().count
             const updatedCount = count + 1
             transaction.update(userCounterRef, {count: updatedCount })
         })
    
    })
    

    【讨论】:

    • Thait 正是我尝试在云功能中进行此计数器更新的原因 :) 所以我删除了 async 和 await,因为它是 Android 和 firebase deploy --only 功能在这两个上给出了错误。但是当有一个新的用户文档时,它仍然不会增加计数器。我需要写什么来代替 {userID}?
    • {userId} 是通配符,您无需在此处更改任何内容。 Android有什么问题?云功能在他们自己的一方工作。你可以分享你的编译错误,看看出了什么问题
    • 对不起,我很困惑,什么意思是说我是用 JavaScript 而不是 Android 编写的,我看到 async await 是用于 TypeScript,我可能错了。
    • 您收到此错误是因为您已删除 async/await 语法,因此您的函数不再是异步的。我已使用经典承诺更新了我的代码。 Async/Await 只是 ES6 的一个特性,与 typescript 无关。
    • np 您可以将其标记为已选择的答案以帮助其他人
    【解决方案2】:

    我在 Cloud Functions 中复制了它,这个简单的解决方案奏效了。 编辑答案以适合 Firebase,它还使用 Firestore dependency 来表示 nodejs。

    const Firestore = require('@google-cloud/firestore');
    const firestore = new Firestore({
      projectId: process.env.GCP_PROJECT,
    });
    
    const functions = require('firebase-functions');
    //I am not using next two lines right now though
    const admin = require('firebase-admin');
    admin.initializeApp();
    
    exports.helloFirestore = 
    functions.firestore.document('users/{userID}').onCreate((event) => {
    
    
      const doc = firestore.doc('Counters/UserCounter/');
      doc.get().then(docSnap => {
        //Get the specific field you want to modify
        return docSnap.get('userCount');
      }).then(field => {
        field++;
        //Log entry to see the change happened
        console.log(`Retrieved field value after +1: ${field}`);
        //Update field of doc with the new value
        doc.update({
          userCount: field,
        });
      });
    });
    

    您使用的通配符应该没问题,请注意集合的完整路径,注意大写/小写。对于这种情况,这就是我的 package.json 的样子:

    {
      "name": "sample-firestore",
      "version": "0.0.1",
      "dependencies": {
        "@google-cloud/firestore": "^1.1.0",
        "firebase-functions": "2.2.0",
        "firebase-admin": "7.0.0"
      }
    }
    

    【讨论】:

    • 我不知道是不是我,但是 doc.get() AND }).then(field lines get error in npm while deploying.
    • 我编辑了我的答案。我现在同时使用 firebase-functions 和 google-cloud/firestore 依赖项来适应 Firebase Cloud Functions。
    猜你喜欢
    • 2023-02-08
    • 2018-03-28
    • 2020-08-02
    • 2011-12-03
    • 2015-11-25
    • 1970-01-01
    • 2015-10-12
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多