使用Firestore runTransaction调用的Firebase云功能大约需要30秒才能完成

时间:2017-10-23 03:52:01

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

此功能最初进行Stripe调用以向用户收费,然后创建交易以更新两个不同的文档 - 相关付款和用户。我不确定如何优化此代码,因为我需要事务逻辑来更新文档。如何优化此功能?

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const moment = require('moment')
admin.initializeApp(functions.config().firebase);
const stripe = require('stripe')(functions.config().stripe.testkey)
const db = admin.firestore();

exports.stripeCharge = functions.firestore   
                                .document('users/{userId}/payments/{paymentId}')
                                .onWrite(event => {

const payment = event.data.data();
const userId = event.params.userId;
const paymentId = event.params.paymentId;

if (!payment || payment.charge) return;

const amount = payment.amount;
const duration = payment.duration;
const createdAt = payment.createdAt;
const idempotency_key = paymentId;
const source = payment.token.id;
const currency = 'usd';
const charge = {amount, currency, source};

return stripe.charges.create(charge, { idempotency_key })
    .then(charge => {
        if (!charge) return;

        var userRef = db.collection('users').doc(userId);
        var paymentsRef = userRef.collection('payments').doc(paymentId);
        var transaction = db.runTransaction(t => {
            return t.get(userRef)
                .then(doc => {
                    let expiresAt;
                    if(doc.data().expiresAt
                      && moment(doc.data().expiresAt).isAfter(createdAt)){
                      expiresAt = moment(doc.data().expiresAt).add(duration, 'M').toDate();
                    }else{
                      expiresAt = moment(createdAt).add(duration, 'M').toDate();
                    }
                    t.update(userRef, { 
                        expiresAt: expiresAt, 
                        timestamp: moment().toDate()
                    });
                    t.update(paymentsRef, { charge: charge });
                });
        })
        .then(result => {
            console.log('Successful');
        })
    })
    .catch(err => { console.log(err) })

});

1 个答案:

答案 0 :(得分:8)

返回交易本身解决了这个问题。

所以不要这样:

var transaction = db.runTransaction(t => {
        return t.get(userRef)
//...

这样做:

return db.runTransaction(t => {
        return t.get(userRef)
//...