KGC*_*beX 6 node.js firebase google-cloud-functions google-cloud-firestore
我的应用程序利用Firestore 函数触发器根据 Firestore 中的更改(例如用户配置文件更改)执行后台操作。例如,如果他们更改手机号码,则会发送验证码。
我有一个触发器,它应该在特定集合上发生onWrite()事件时运行。onWrite()在 Firebase 中针对特定集合发生以下任何操作时运行:
在我的用例中,我需要它为onCreate()and运行onUpdate(),因此我使用onWrite()
要使Firebase 触发器正常工作,除了表示已创建/更改/删除的文档的文档 ID/通配符之外,还需要特定格式。
常数:
const collections = {
...
conversations: "conversations",
...
}
Run Code Online (Sandbox Code Playgroud)
可调用函数(更新 firestore):
/**
* Add an conversation to conversations collection
* @type {HttpsFunction & Runnable<any>}
*/
exports.addConversations = functions.https.onCall(async (data, context) => {
// expects conversation & interested state
const {valid, errors} = validateRequiredBody(data, [
"conversation",
]);
if (!valid) {
return {
status: false,
message: "Missing or invalid parameters",
errors: errors,
jwtToken: "",
};
}
// get conversation item
const conversation = {
id: data["conversation"]["id"],
name: data["conversation"]["name"],
}
// create conversation with empty counter
// let writeResult = await collectionRefs.conversationsRef.doc(conversation.id).set({
let writeResult = await admin.firestore().collection(collections.conversations).doc(conversation.id).set({
id: conversation.id,
name: conversation.name,
count: 0
});
console.log(`[function-addConversations] New Conversation [${conversation.name}] added`);
return {
status: true,
message: ""
}
});
Run Code Online (Sandbox Code Playgroud)
Firestore 触发器(不触发):
/**
* On conversations updated/removed, update corresponding counter
* @type {CloudFunction<Change<QueryDocumentSnapshot>>}
*/
exports.onConversationProfileCollectionCreate = functions.firestore.document(`${collections.conversations}/{id}`)
.onWrite(async snapshot => {
console.log("Conversation Collection Changed");
// let conversation = collectionRefs.conversationsRef.doc(snapshot.id);
// await conversation.update({count: FieldValue.increment(1)});
});
Run Code Online (Sandbox Code Playgroud)
在我的移动应用程序中,用户(调用)addConversations()firebase 函数,这将新对话添加到 Firestore,这是清晰可见的,但计数器触发器(触发函数)没有运行。
模拟器输出:
...
{"verifications":{"app":"MISSING","auth":"MISSING"},"logging.googleapis.com/labels":{"firebase-log-type":"callable-request-verification"},"severity":"INFO","message":"Callable request verification passed"}
[function-addConversations] New Conversation [Test Conversation Topic] added
Profile updated
(print profile data)
...
Run Code Online (Sandbox Code Playgroud)
我应该期待看到的:
...
{"verifications":{"app":"MISSING","auth":"MISSING"},"logging.googleapis.com/labels":{"firebase-log-type":"callable-request-verification"},"severity":"INFO","message":"Callable request verification passed"}
[function-addConversations] New Conversation [Test Conversation Topic] added
Conversation Collection Changed // this is output by the trigger
Profile updated
(print profile data)
...
Run Code Online (Sandbox Code Playgroud)
我做错什么了吗?
这个问题是一个离我们家较近的问题。
我正在使用firebase 模拟器进行开发,并使用 Flutter 的 firebase 包中内置的模拟器功能中的模拟器连接到它们。
Firebase 模拟器设置(例如Firebase 功能)可以在此处找到
长话短说:
启动 Firebase 模拟器时,您应该看到类似以下内容的内容:
C:\Users\User\MyApp\awesome-app-server>firebase emulators:start --only functions
i emulators: Starting emulators: functions
! functions: You are running the functions emulator in debug mode (port=9229). This means that functions will execute in sequence rather than in parallel.
! functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, firestore, database, hosting, pubsub, storage
! Your requested "node" version "12" doesn''t match your global version "14"
i ui: Emulator UI logging to ui-debug.log
i functions: Watching "C:\Users\User\MyApp\awesome-app-server\functions" for Cloud Functions...
> Debugger listening on ws://localhost:9229/03dc1d62-f2a3-418e-a343-bb0b357f7329
> Debugger listening on ws://localhost:9229/03dc1d62-f2a3-418e-a343-bb0b357f7329
> For help, see: https://nodejs.org/en/docs/inspector
! functions: The Cloud Firestore emulator is not running, so calls to Firestore will affect production.
! functions: The Realtime Database emulator is not running, so calls to Realtime Database will affect production.
...
Run Code Online (Sandbox Code Playgroud)
但是你会看到这一点 -这非常重要!
i functions[us-central1-api-user-onConversationProfileCollectionCreate ]: function ignored because the database emulator does not exist or is not running.
Run Code Online (Sandbox Code Playgroud)
这是因为 Firestore 和(实时)数据库使用在函数中找到的触发器,因此函数期望找到本地 firestore/数据库模拟器。
由于本地没有运行 firestore/数据库模拟器
! functions: The Cloud Firestore emulator is not running, so calls to Firestore will affect production.
! functions: The Realtime Database emulator is not running, so calls to Realtime Database will affect production.
Run Code Online (Sandbox Code Playgroud)
并且这些函数不会自动附加到生产 Firestore/数据库(这可能会造成破坏),这些触发器在本地模拟时没有按我预期的方式运行。
解决方案:
在本地模拟 firestore 和数据库(请参阅此内容将您的 firestore 数据导入到本地模拟器)firebase emulators:start --only functions,...,firestore,database
上传函数以与 Firestore/数据库配合使用(请小心执行此操作)
更多细节:
下面我提供了导致我出现问题的详细信息,以及我如何解决这个问题:
我在做什么:
firebase emulators:start --inspect-functions --only functions,auth
Run Code Online (Sandbox Code Playgroud)
我已经在 Firestore 中预填充了数据,因此我打算在本地模拟时使用 Firestore 数据,该数据已按预期工作,但由于在本地模拟,Firebase Firestore 和数据库触发器将无法工作。
我知道我的一些触发器实际上确实正确触发,因此它一定是某种配置错误。
扩展解决方案(将 firestore 数据导入本地模拟器)
firebase 模拟器:start --inspect-functions --only 函数,auth,firestore,数据库
注意最后 2 个,firestore 和数据库 - 应该添加这个以便触发器在本地工作
从生产 Firestore 导入数据
使用生产(在开发期间)firestore 的原因是不为每个测试重新创建所有数据。解决方案是从 firestore 导出并将数据导入到模拟器中。
有关详细信息,请参阅此内容 - 我无法从终端导出,因此我转到 Google Console 导出到存储桶,并通过控制台从那里下载它。
要启动模拟器(并允许调试 firebase 功能),我使用:
firebase emulators:start --inspect-functions --import ./functions/{path/to/data} --only functions,auth,firestore,database
Run Code Online (Sandbox Code Playgroud)
细节:
firebase emulators:start- 启动模拟器--inspect-functions允许通过 websockets 进行调试功能 - 例如端口 9229 上的 Webstorm NodeJs 调试器--import ./functions/{path/to/data}- 使用项目根目录将数据导入到 firestore 模拟器./--only functions,auth,firestore,database指定要模拟的模块| 归档时间: |
|
| 查看次数: |
351 次 |
| 最近记录: |