如何在另一个函数中移动交易代码



我正在尝试使用事务重写firebase函数。我现在遇到的问题是,我是否应该归还一份转写承诺?例如,我想使用一个函数,它有一个transception参数。但是这个函数不应该立即执行交易,而是返回它的Promise

这是我目前的功能:

export const dbUserDocsOnCreated = functions
.region(constants.region)
.firestore
.document("users/{id}")
.onCreate((snapshot, context) => doOnCreatedUserDocs(db, stripe, snapshot, context));

export async function doOnCreatedUserDocs(
db: FirebaseFirestore.Firestore, 
stripe: Stripe, 
snapshot: functions.firestore.QueryDocumentSnapshot, 
context: functions.EventContext
) {
try {
const transactionPromise = db.runTransaction(async (t) => {
const snapshotData: FirebaseFirestore.DocumentData = (await t.get(snapshot.ref)).data() as FirebaseFirestore.DocumentData

// IF onCreate() has already been called once.
if (!isDataNullOrEmpty(snapshotData.eventID)) {
return Promise.all([null])
}
const createdUserNr: string = await getIdTransactionally(t, db, constants.collectionUsers)
const createdStripeUser: Stripe.Response<Stripe.Customer> = await createStripeUser(stripe, snapshotData, firebaseUserEmail, currentUserNr, snapshot.id, idempotencyKey)

const updateUserNrPromise: Promise<FirebaseFirestore.Transaction> = incrementIdTransactionally(t, db,  constants.collectionUsers)
const updateUserDocsPromise: Promise<FirebaseFirestore.Transaction> = updateUserDocsTransactionally(t, snapshot.ref, createdUserNr, idempotencyKey)
return Promise.all([
updateUserDocsPromise,
updateUserNrPromise,
])
})
return Promise.all([
transactionPromise
])
} catch (err) {
// CATCHING
}
}

处理事务的已用函数

export async function incrementIdTransactionally(
transaction: FirebaseFirestore.Transaction, 
db: FirebaseFirestore.Firestore, 
doc: string
): Promise<FirebaseFirestore.Transaction> {
const incrementor: FirebaseFirestore.FieldValue = FirebaseFirestore.FieldValue.increment(1);
const collectionReference: FirebaseFirestore.DocumentReference<FirebaseFirestore.DocumentData> = db.collection(constants.collectionAutoIds).doc(doc)
return transaction.update(collectionReference, { id: incrementor })
}
async function updateUserDocsTransactionally(
transaction: FirebaseFirestore.Transaction, 
ref: FirebaseFirestore.DocumentReference, 
generatedUserNr: String,
eventId: string,
): Promise<FirebaseFirestore.Transaction> {
return transaction.set(ref, { 
userNr: generatedUserNr, 
eventId: eventId,
optionalAddress: FirebaseFirestore.FieldValue.delete() 
}, { merge: true })
}
function createStripeUser(
stripe: Stripe, 
data: FirebaseFirestore.DocumentData, 
eMail: string, 
usernr: string, 
uid: string,
idempotencKey: string,
): Promise<Stripe.Response<Stripe.Customer>> {
return stripe.customers.create({
name: data.fullName,
email: eMail,
description: "Created by Firebase Cloud-Functions",
metadata: { uuid: uid, userNr: usernr },
preferred_locales: ["de-DE"],
}, { idempotencyKey: idempotencKey })
}

查看上一个线程和SDK引用后,事务的set()update()delete()操作似乎没有返回promise,但它们只是返回相同的Transaction实例以用于事务链接:

返回事务:此事务实例。用于链接方法调用。

这与返回Promise<DocumentSnapshot>get()方法不同。我测试了一个分为两个功能的简单事务,没有发现明显的问题:


function fireTransaction(){
return fireDB.runTransaction((tr) => {
const myDoc = fireDB.collection("users").doc("testUser1");
return tr.get(myDoc).then(tDoc => {
setUserAgeTR(tr, tDoc.ref)
})
})
.then(res => console.log("Completed"))
.catch(err => console.log("Failed Transaction: ", err))
}
function setUserAgeTR(tr, docRef){
return tr.update(docRef, {userAge: 9999}) //Requires DocumentReference, can be obtained from 'ref'
}

根据SDK文档,由于您使用的是TypeScript,辅助函数的返回类型应该是Transaction

相关内容

  • 没有找到相关文章

最新更新