使用 Cloud Function 在 Firestore 上写入数据突然失败
Posted
技术标签:
【中文标题】使用 Cloud Function 在 Firestore 上写入数据突然失败【英文标题】:Writing data on Firestore sudden fail with Cloud Function 【发布时间】:2020-11-02 08:24:52 【问题描述】:我在 Cloud Function 中有 5 个预定功能,几个月来一切正常,但今天它突然似乎失败了,或者没有等待 Firestore 完成更新。这是超时还是服务停机?目前所有 5 个预定函数都会调用 updateFunction()
来更新 Firestore 文档中的某些字段,但只是这次更新部分没有成功。
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
/*
* 'onCreate' triggered when a document is written to for the first time.
* 'onDelete' triggered when a document with data is deleted.
* 'OnWrite' works as 'addValueEventListener' or 'addSnapshotListener' for android.
* It will fire the function every time there is some item added, removed or changed
* from the provided 'database.ref'.
*
*/
const settingsConfig = timestampsInSnapshots: true ;
const db = admin.firestore();
db.settings(settingsConfig);
//Message priority must be one of normal or high.
const options = priority: 'high' ;
exports.schedTask3 = functions.pubsub.schedule('0 11 * * 1')
.timeZone('Asia/Manila') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) =>
//This will be run every Monday at 11:00 AM
updateFunction();
);
//THIS FUNCTION IS BEING USE BY 5 SCHEDULE FUNCTION (schedTask1 to schedTask5)
function updateFunction()
const dateFormat = require('dateformat');
dateFormat.i18n =
dayNames: [
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',
'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
],
monthNames: [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
],
timeNames: [
'a', 'p', 'am', 'pm', 'A', 'P', 'AM', 'PM'
]
;
//SUDDENLY DID NOT REACH THEN RESULT FOR THE FIRST TIME AFTER MONTHS OF WORKING
return db
.collection("Lorem")
.doc("Lorem")
.set(
date: dateFormat(new Date().getTime(), "dd mmmm yyyy"),
value: "Lorem"
)
.then(result =>
const payload =
data:
title: "Lorem",
description: "Lorem",
bigImage: "Lorem",
link: "Lorem",
environment: "release",
;
pushNotif(payload);
console.log("Updating prediction is success.");
).catch(error =>
return console.error("Failed to send notification.", error);
)
function pushNotif(payload)
return admin.messaging().sendToTopic("Announcement", payload, options)
.then(val =>
return console.log("Success!\n" + JSON.stringify(payload), val);
)
.catch(error =>
return console.error("Failed to send notification.", error);
);
【问题讨论】:
【参考方案1】:这是因为您错误地管理了 Cloud Function 的生命周期。
在后台调用异步方法的 Cloud Functions 中返回一个 Promise(或一个值)是很重要的,以便告诉 Cloud Functions 平台等到 Promise 被履行或拒绝后再清理函数。详情请参阅https://firebase.google.com/docs/functions/terminate-functions。
在您的情况下,会发生以下情况:有时,Cloud Functions 平台不会立即清理您的 Cloud Function,而 Cloud Functions 可以完成。但在其他情况下,由于您没有返回承诺,Cloud Functions 平台会在完成前对其进行清理。
以下更改(除其他外,请参阅添加几个 return
s)应该可以解决问题(未经测试):
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
/*
* 'onCreate' triggered when a document is written to for the first time.
* 'onDelete' triggered when a document with data is deleted.
* 'OnWrite' works as 'addValueEventListener' or 'addSnapshotListener' for android.
* It will fire the function every time there is some item added, removed or changed
* from the provided 'database.ref'.
*
*/
const settingsConfig = timestampsInSnapshots: true ;
const db = admin.firestore();
db.settings(settingsConfig);
//Message priority must be one of normal or high.
const options = priority: 'high' ;
exports.schedTask3 = functions.pubsub.schedule('0 11 * * 1')
.timeZone('Asia/Manila') // Users can choose timezone - default is America/Los_Angeles
.onRun((context) =>
//This will be run every Monday at 11:00 AM
return updateFunction()
.catch(error =>
console.log(error);
return null;
)
);
//THIS FUNCTION IS BEING USE BY 4 SCHEDULE FUNCTION (schedTask1 to schedTask5)
function updateFunction()
const dateFormat = require('dateformat');
dateFormat.i18n =
dayNames: [
'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat',
'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'
],
monthNames: [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
'Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'
],
timeNames: [
'a', 'p', 'am', 'pm', 'A', 'P', 'AM', 'PM'
]
;
//SUDDENLY DID NOT REACH THEN RESULT FOR THE FIRST TIME AFTER MONTHS OF WORKING
return db
.collection("Lorem")
.doc("Lorem")
.set(
date: dateFormat(new Date().getTime(), "dd mmmm yyyy"),
value: "Lorem"
)
.then(result =>
const payload =
data:
title: "Lorem",
description: "Lorem",
bigImage: "Lorem",
link: "Lorem",
environment: "release",
;
return pushNotif(payload);
).catch(error =>
// throw an error e.g. throw new Error('....'), see https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Error
)
function pushNotif(payload)
return admin.messaging().sendToTopic("Announcement", payload, options)
.then(val =>
console.log("Success!\n" + JSON.stringify(payload), val);
return null;
)
.catch(error =>
// throw an error e.g. throw new Error('....'), see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
);
我建议您观看 Firebase 视频系列中关于“JavaScript Promises”的 3 个视频:https://firebase.google.com/docs/functions/video-series/。
【讨论】:
就是这样!感谢您突然帮助我理解这些代码出了什么问题。以上是关于使用 Cloud Function 在 Firestore 上写入数据突然失败的主要内容,如果未能解决你的问题,请参考以下文章
大型集合的 Firestore DeadlineExceeded 异常
如何通过 Cloud Build 访问 GSM 机密并传递给 Cloud Function
使用 Cloud Function 在 Firestore 上写入数据突然失败
在 TypeScript 中为 Firebase Cloud Function 配置 mailgun
在 Cloud Function 的 chrome-drive 中将下载目录设置为 Cloud Storage
如何在 Google Cloud Function 上的 Spring Cloud 函数中获取 Pub/Sub 事件的元数据