Node.js 在云Firestore上添加文档时更新字段

Node.js 在云Firestore上添加文档时更新字段,node.js,firebase,google-cloud-firestore,Node.js,Firebase,Google Cloud Firestore,我有一个关于在我的Android应用程序中使用云Firestore功能的问题,我正在使用Android Studio在kotlin上编写 阅读了一些文档后,我认为在数据库中创建新文档时,可以在Firestore函数中运行自定义方法。我需要做的就是更新一个字段 问题是云Firestore上的这些函数需要用JavaScript编写,我需要使用Node.js,我对此一无所知 对于任何具有云Firestore知识的开发人员,有关于此问题的指南或提示吗 问题是云Firestore上的这些函数需要用Java

我有一个关于在我的Android应用程序中使用云Firestore功能的问题,我正在使用Android Studio在kotlin上编写

阅读了一些文档后,我认为在数据库中创建新文档时,可以在Firestore函数中运行自定义方法。我需要做的就是更新一个字段

问题是云Firestore上的这些函数需要用JavaScript编写,我需要使用Node.js,我对此一无所知

对于任何具有云Firestore知识的开发人员,有关于此问题的指南或提示吗

问题是云Firestore上的这些函数需要用JavaScript编写,我需要使用Node.js,我对此一无所知

不知道它是否有用,但云函数也可以用Python或Go编写。您可以查看有关当前运行时和语言的更完整信息

但让我们试着回答你的问题,好吗?我将在下面的示例中使用Node.js 8运行时

介绍 谷歌云功能目前支持两种类型的功能:

,由简单的HTTP请求触发,以及 ,这是由来自谷歌云基础设施的事件触发的,例如云Firestore事件。这就是你需要的,所以让我们集中精力。 安装程序 由于您正在使用Cloud Firestore,我假设您已经设置了Firebase项目。因此,如果您还没有,第一步是安装,并按照其说明在本地设置项目。当被询问时,选择Functions:Configure and deploy Cloud Functions选项以启用它,并使用现有项目选择您的项目

$ firebase login
$ firebase init
完成安装后,目录中基本上将具有以下结构:

firebase.json
.firebaserc
functions/
    index.js
    package.json
现在,在开始编码之前,您应该了解云Firestore事件。其中有4个,列表如下:

onCreate:首次写入文档时触发。 onUpdate:当文档已存在且任何值已更改时触发。 onDelete:删除带数据的单据时触发

onWrite:在触发onCreate、onUpdate或onDelete时触发

因为您只需要捕获一个创建事件,所以将编写一个onCreate事件

编码 为此,请打开functions/index.js文件并键入以下代码:

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

// this function is triggered by "onCreate" Cloud Firestore events
// the "userId" is a wildcard that represents the id of the document created inside te "users" collection
// it will read the "email" field and insert the "lowercaseEmail" field
exports.onCreateUserInsertEmailLowercase = functions.firestore
    .document('users/{userId}')
    .onCreate((snapshot, context) => {
        // "context" has info about the event
        // reference: https://firebase.google.com/docs/reference/functions/cloud_functions_.eventcontext
        const { userId } = context.params;

        // "snapshot" is a representation of the document that was inserted
        // reference: https://googleapis.dev/nodejs/firestore/latest/DocumentSnapshot.html
        const email = snapshot.get('email');

        console.log(`User ${userId} was inserted, with email ${email}`);

        return null;
    });
正如您可能猜到的,这是一个非常简单的云函数,它只记录文档的id及其电子邮件字段。现在我们来看问题的第二部分:我们如何编辑这个新创建的文档?这里有两个选项:1更新您刚刚创建的文档,2更新其他文档,因此我将其分为两个部分:

1更新您刚刚创建的文档 答案在于snapshot参数。虽然它只是您插入的文档的表示形式,但它在其中携带了一个,这是一种不同类型的对象,具有读取、写入和侦听更改的功能。让我们使用它的方法插入新字段。因此,让我们更改当前函数以实现此目的:

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

// this function is triggered by "onCreate" Cloud Firestore events
// the "userId" is a wildcard that represents the id of the document created inside te "users" collection
// it will read the "email" field and insert the "lowercaseEmail" field
exports.onCreateUserInsertEmailLowercase = functions.firestore
    .document('users/{userId}')
    .onCreate((snapshot, context) => {
        // "context" has info about the event
        // reference: https://firebase.google.com/docs/reference/functions/cloud_functions_.eventcontext
        const { userId } = context.params;

        // "snapshot" is a representation of the document that was inserted
        // reference: https://googleapis.dev/nodejs/firestore/latest/DocumentSnapshot.html
        const email = snapshot.get('email');

        console.log(`User ${userId} was inserted, with email ${email}`);

        // converts the email to lowercase
        const lowercaseEmail = email.toLowerCase();

        // get the DocumentReference, with write powers
        const documentReference = snapshot.ref;

        // insert the new field
        // the { merge: true } parameter is so that the whole document isn't overwritten
        // that way, only the new field is added without changing its current content
        return documentReference.set({ lowercaseEmail }, { merge: true });
    });
2从另一个集合更新文档 为此,您需要在项目中添加。它具有所有管理员权限,因此您可以写入项目中的任何Cloud Firestore文档

$ firebase login
$ firebase init
在functions目录中,运行:

$ npm install --save firebase-admin
$ firebase deploy --only functions:onCreateUserInsertEmailLowercase
$ firebase deploy --only functions:onCreateUpdateUsersCounter                                 
由于您已经进入Google Cloud的基础设施,初始化它非常简单,只需在index.js文件中添加以下几行即可:

现在,您所要做的就是使用AdminSDK获取要更新的文档的DocumentReference,并使用它更新其中的一个字段

对于这个例子,我将考虑您有一个名为STATS的集合,它包含一个用户文档,里面有一个计数器,用来跟踪用户集合中的文档数量:

// this updates the user count whenever a document is created inside the "users" collection
exports.onCreateUpdateUsersCounter = functions.firestore
.document('users/{userId}')
.onCreate(async (snapshot, context) => {
    const statsDocumentReference = admin.firestore().doc('stats/users');

    // a DocumentReference "get" returns a Promise containing a DocumentSnapshot
    // that's why I'm using async/await
    const statsDocumentSnapshot = await statsDocumentReference.get();
    const currentCounter = statsDocumentSnapshot.get('counter');

    // increased counter
    const newCounter = currentCounter + 1;

    // update the "counter" field with the increased value
    return statsDocumentReference.update({ counter: newCounter });
});
就这样

部署 但是现在您已经有了编码部分,如何部署它以使其在项目中运行,对吗?让我们再次使用Firebase CLI来部署新的云功能

在项目的根目录中,运行:

$ npm install --save firebase-admin
$ firebase deploy --only functions:onCreateUserInsertEmailLowercase
$ firebase deploy --only functions:onCreateUpdateUsersCounter                                 
这几乎是基础,但如果您愿意,可以查看有关部署云功能的更多信息

调试 好吧,对,但我们怎么知道它起作用了?去试试吧!插入几个文档,看看神奇的事情发生了。如果你需要一点调试,点击左边的函数菜单,你就可以访问你的函数日志了

对于您的用例场景来说,这差不多就是它了,但如果您想更深入地了解云功能,我真的建议您使用它的文档。它相当完整、简洁、有条理。我留下了一些链接作为参考,这样你就知道去哪里找了

干杯

问题是云Firestore上的这些函数需要用JavaScript编写,我需要使用Node.js,我对此一无所知。

不知道它是否有用,但云函数也可以用Python或Go编写。您可以查看有关当前运行时和语言的更完整信息

但让我们试着回答你的问题,好吗?我将在下面的示例中使用Node.js 8运行时

介绍 谷歌云功能目前支持两种类型的功能:

,由简单的HTTP请求触发,以及 ,这是由来自谷歌云基础设施的事件触发的,例如云Firestore事件。这就是你需要的,所以让我们集中精力。 安装程序 由于您正在使用Cloud Firestore,我假设您已经设置了Firebase项目。因此,如果您还没有,第一步是安装,并按照其说明在本地设置项目。当被询问时,选择Functions:Configure and deploy Cloud Functions选项以启用它,并使用现有项目选择您的项目

$ firebase login
$ firebase init
完成安装后,目录中基本上将具有以下结构:

firebase.json
.firebaserc
functions/
    index.js
    package.json
现在,在开始编码之前,您应该了解云Firestore事件。其中有4个,列表如下:

onCreate:首次写入文档时触发。 onUpdate:当文档已存在且任何值已更改时触发。 onDelete:删除带数据的单据时触发

onWrite:在触发onCreate、onUpdate或onDelete时触发

因为您只需要捕获一个创建事件,所以将编写一个onCreate事件

编码 为此,请打开functions/index.js文件并键入以下代码:

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

// this function is triggered by "onCreate" Cloud Firestore events
// the "userId" is a wildcard that represents the id of the document created inside te "users" collection
// it will read the "email" field and insert the "lowercaseEmail" field
exports.onCreateUserInsertEmailLowercase = functions.firestore
    .document('users/{userId}')
    .onCreate((snapshot, context) => {
        // "context" has info about the event
        // reference: https://firebase.google.com/docs/reference/functions/cloud_functions_.eventcontext
        const { userId } = context.params;

        // "snapshot" is a representation of the document that was inserted
        // reference: https://googleapis.dev/nodejs/firestore/latest/DocumentSnapshot.html
        const email = snapshot.get('email');

        console.log(`User ${userId} was inserted, with email ${email}`);

        return null;
    });
正如您可能猜到的,这是一个非常简单的云函数,它只记录文档的id及其电子邮件字段。现在我们来看问题的第二部分:我们如何编辑这个新创建的文档?这里有两个选项:1更新您刚刚创建的文档,2更新其他文档,因此我将其分为两个部分:

1更新您刚刚创建的文档 答案在于snapshot参数。虽然它只是您插入的文档的表示形式,但它在其中携带了一个,这是一种不同类型的对象,具有读取、写入和侦听更改的功能。让我们使用它的方法插入新字段。因此,让我们更改当前函数以实现此目的:

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

// this function is triggered by "onCreate" Cloud Firestore events
// the "userId" is a wildcard that represents the id of the document created inside te "users" collection
// it will read the "email" field and insert the "lowercaseEmail" field
exports.onCreateUserInsertEmailLowercase = functions.firestore
    .document('users/{userId}')
    .onCreate((snapshot, context) => {
        // "context" has info about the event
        // reference: https://firebase.google.com/docs/reference/functions/cloud_functions_.eventcontext
        const { userId } = context.params;

        // "snapshot" is a representation of the document that was inserted
        // reference: https://googleapis.dev/nodejs/firestore/latest/DocumentSnapshot.html
        const email = snapshot.get('email');

        console.log(`User ${userId} was inserted, with email ${email}`);

        // converts the email to lowercase
        const lowercaseEmail = email.toLowerCase();

        // get the DocumentReference, with write powers
        const documentReference = snapshot.ref;

        // insert the new field
        // the { merge: true } parameter is so that the whole document isn't overwritten
        // that way, only the new field is added without changing its current content
        return documentReference.set({ lowercaseEmail }, { merge: true });
    });
2从另一个集合更新文档 为此,您需要在项目中添加。它具有所有管理员权限,因此您可以写入项目中的任何Cloud Firestore文档

$ firebase login
$ firebase init
在functions目录中,运行:

$ npm install --save firebase-admin
$ firebase deploy --only functions:onCreateUserInsertEmailLowercase
$ firebase deploy --only functions:onCreateUpdateUsersCounter                                 
由于您已经进入Google Cloud的基础设施,初始化它非常简单,只需在index.js文件中添加以下几行即可:

现在,您所要做的就是使用AdminSDK获取要更新的文档的DocumentReference,并使用它更新其中的一个字段

对于这个例子,我将考虑您有一个名为STATS的集合,它包含一个用户文档,里面有一个计数器,用来跟踪用户集合中的文档数量:

// this updates the user count whenever a document is created inside the "users" collection
exports.onCreateUpdateUsersCounter = functions.firestore
.document('users/{userId}')
.onCreate(async (snapshot, context) => {
    const statsDocumentReference = admin.firestore().doc('stats/users');

    // a DocumentReference "get" returns a Promise containing a DocumentSnapshot
    // that's why I'm using async/await
    const statsDocumentSnapshot = await statsDocumentReference.get();
    const currentCounter = statsDocumentSnapshot.get('counter');

    // increased counter
    const newCounter = currentCounter + 1;

    // update the "counter" field with the increased value
    return statsDocumentReference.update({ counter: newCounter });
});
就这样

部署 但是现在您已经有了编码部分,如何部署它以使其在项目中运行,对吗?让我们再次使用Firebase CLI来部署新的云功能

在项目的根目录中,运行:

$ npm install --save firebase-admin
$ firebase deploy --only functions:onCreateUserInsertEmailLowercase
$ firebase deploy --only functions:onCreateUpdateUsersCounter                                 
这几乎是基础,但如果您愿意,可以查看有关部署云功能的更多信息

调试 好吧,对,但我们怎么知道它起作用了?去试试吧!插入几个文档,看看神奇的事情发生了。如果你需要一点调试,点击左边的函数菜单,你就可以访问你的函数日志了

对于您的用例场景来说,这差不多就是它了,但如果您想更深入地了解云功能,我真的建议您使用它的文档。它相当完整、简洁、有条理。我留下了一些链接作为参考,这样你就知道去哪里找了


干杯

关于堆栈溢出,请限制您自己在每篇文章中只回答一个问题。我在这里读到两个非常不同的问题。有一个以上问题的帖子有被关闭的风险,所以我建议将其编辑为一个。另外,请明确您使用的是哪个平台。你一开始说你有recyclerviews,它建议使用android,但你的问题被标记为node.js。您使用哪个平台进行查询?查看到目前为止您拥有的代码,更清楚地了解您正在做什么,这也是非常有帮助的。谢谢!完成了。把我的整个问题重新表述一下。我建议从。堆栈溢出不是要求外部资源或链接的地方-您最好发布到讨论组,如reddit。对于堆栈溢出,请将您自己的问题限制为每篇文章一个问题。我在这里读到两个非常不同的问题。带有多个问题的帖子位于
有被关闭的风险,所以我建议将其编辑为一个。另外,请明确您使用的是哪个平台。你一开始说你有recyclerviews,它建议使用android,但你的问题被标记为node.js。您使用哪个平台进行查询?查看到目前为止您拥有的代码,更清楚地了解您正在做什么,这也是非常有帮助的。谢谢!完成了。把我的整个问题重新表述一下。我建议从。堆栈溢出不是一个要求外部资源或链接的地方-你最好发布到一个讨论组,比如reddit。Fernando,这太棒了!我现在正在做这件事,真的,谢谢你!我还有一个问题,对不起,我想我在原来的问题中没有说清楚。当我创建这个新文档时,我需要更新另一个文档上的字段。假设我在文档上有一个字段,用于跟踪我的文档总数,这只是一个示例。所以每次我创建一个新文档时,这个字段应该是+1。鉴于您编写的代码中的变量已连接到我的新文档,是否可以访问其他文档?使用FirebaseFirestore,我可以在我的android应用程序上完成,但这绝对是后端服务器的工作,而不是android应用程序的工作。@Agustimagne在我看来,您确实希望更新当前文档。但是别担心!我刚刚编辑了我的答案,也包括了这个其他场景,请再看一看:这太棒了,谢谢!费尔南多,这太棒了!我现在正在做这件事,真的,谢谢你!我还有一个问题,对不起,我想我在原来的问题中没有说清楚。当我创建这个新文档时,我需要更新另一个文档上的字段。假设我在文档上有一个字段,用于跟踪我的文档总数,这只是一个示例。所以每次我创建一个新文档时,这个字段应该是+1。鉴于您编写的代码中的变量已连接到我的新文档,是否可以访问其他文档?使用FirebaseFirestore,我可以在我的android应用程序上完成,但这绝对是后端服务器的工作,而不是android应用程序的工作。@Agustimagne在我看来,您确实希望更新当前文档。但是别担心!我刚刚编辑了我的答案,也包括了这个其他场景,请再看一看:这太棒了,谢谢!