Firebase云事务触发错误

时间:2019-03-06 03:33:23

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

我正在尝试通过Firestore事务创建分布式计数器。我有一个帖子集,每个帖子都有一个“ count_shards”子集。它们每个都有三个文档(1、2、3),其中包含一个“计数”字段。

当我为帖子创建一个“喜欢”文档时,我想选择一个随机文档并将其递增1。我有以下打字稿代码:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

exports.addShard = functions.firestore
    .document(`likes/{docID}`)
    .onCreate(async (snap, context) => {
        const postID: string = snap.data().postID;
        const randNum: number = (Math.floor(Math.random()*3+1)); 
        const postRef = admin.firestore().doc(`post/${postID}/count_shards/${randNum}`);

        admin.firestore().runTransaction(async transaction => {
            const postShard = (await transaction.get(postRef)).data();
            postShard.count += 1;
            return transaction.update(postRef, postShard);
        });

    });

我收到以下错误消息:

“错误:/Users//firecast/functions/src/index.ts [13、9]:承诺必须得到适当处理”

“功能@棉绒:tslint --project tsconfig.json

有人知道我在做什么错吗?

2 个答案:

答案 0 :(得分:1)

runTransaction返回一个承诺。您需要await

    await admin.firestore().runTransaction(...);

答案 1 :(得分:0)

runTransaction方法返回一个Promise。 正如this blog post所说:您必须退回Promise

这些很重要:

  

...如果您希望某个函数在异步工作期间保持活动状态,可以通过从该函数返回一个承诺(HTTP / S触发器除外,该触发器需要将响应发送到客户端)来实现。

或者换句话说:如果不返回该Promise,则您的函数可以在不完成transaction的情况下完成。

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();

exports.addShard = functions.firestore
    .document(`likes/{docID}`)
    .onCreate(async (snap, context) => {
        const postID: string = snap.data().postID;
        const randNum: number = (Math.floor(Math.random()*3+1)); 
        const postRef = admin.firestore().doc(`post/${postID}/count_shards/${randNum}`);

        return admin.firestore().runTransaction(async transaction => {
            const postShard = (await transaction.get(postRef)).data();
            postShard.count += 1;
            return transaction.update(postRef, postShard);
        });

    });