Firebase功能偶尔无法完成执行

时间:2018-07-27 17:12:28

标签: mongodb firebase google-cloud-functions

我建立了一个由Firestore“文档创建”事件触发的firebase云功能

该功能连接到MongoDB集群(在MongoDB Atlas上运行),修改将其存储在数据库集合中的Firestore数据

函数本身在每次写入文档时都会执行

但是它没有完成执行,这是零星的,例如每10个中的1个左右,执行将无法完成,即“错误连接”或“连接成功”行均未执行

同一代码将另外执行9/10次(大约)

这是该代码的精简版本

import * as functions from 'firebase-functions';
import { MongoClient } from "mongodb";

exports.migrate = functions.firestore
    .document('{rootCollection}/{tenantName}/users/{userId}/entry/{entryId}')
    .onCreate((snap, context) => {

    const uri = "mongodb://localhost:27017/";

    console.log("Attempting to connect to mongoclient");

    MongoClient.connect(uri, function(err, client) {

        if (err) {
                console.log("error connecting");
                return 1;
            }        
            else if (client) {
              console.log("Connected to mongoclient");
              //write to mongodb collection here
            }
       });
});

这是一次成功的执行,红色的日志消息突出显示了MongoClient连接后执行的块中的代码(打印了一些额外的日志消息)

enter image description here

这是执行失败

enter image description here

编辑:

根据道格的回答,这就是我的解决方法-我们不仅需要返回一个Promise,而且还要将连接返回的Promise链接起来,并插入两个语句

exports.migrate = functions.firestore
.document('{rootCollection}/{tenantName}/users/{userId}/entry/{entryId}')
    .onCreate((snap, context) => {

    const uri = "mongodb://localhost:27017/";

    console.log("Attempting to connect to mongoclient");

    return MongoClient.connect(uri).then((client) => {
        console.log("Connected successfully");
        return client.db("test")
            .collection("testcollection")
            .insertOne({"name": "1"})
                .then((() => {
                    console.log("inserted successfully");
                    client.close(true)
                        .then(()=>{console.log("connection close OK")})
                        .catch(()=>{console.log("connection close Err")});
                }))
                .catch(() => {
                    console.log("error in insertion");
                    client.close(true)
                        .then(()=>{console.log("connection close OK")})
                        .catch(()=>{console.log("connection close Err")});
                });

    })
    .catch(() => console.log("connection failure"));

我确定这次是因为代码按我想要的顺序执行,因为我可以在云功能日志中看到它们:

  1. 功能已启动(系统消息)
  2. 尝试连接(用户消息)
  3. 连接成功(用户消息)
  4. 已成功插入(用户消息)
  5. 连接已关闭(用户消息)
  6. 功能已结束(系统消息)

1 个答案:

答案 0 :(得分:0)

您需要返回一个仅在功能中所有工作完成后才能解决的承诺。 /** * Removes all headers provided via array of 'headerPatterns'. As the name suggests the array * may contain simple matching patterns for header names. Supported pattern styles are: * "xxx*", "*xxx", "*xxx*" and "xxx*yyy". * * @param headerPatterns The header patterns. * @return this. */ public abstract AbstractIntegrationMessageBuilder<T> removeHeaders(String... headerPatterns); 几乎可以肯定是一个立即返回的异步函数,您传递给它的回调在一段时间后执行。因为它立即返回,所以数据库触发器将立即返回,并且Cloud Functions假定其工作已完成。似乎只有偶尔会在Cloud Functions关闭您的函数之前调用您的回调。