简体   繁体   English

无法在 Firestore 集合中写入批处理文档

[英]Unable to write batch document in firestore collection

My function receives data from a mobile app.我的 function 从移动应用程序接收数据。 When a CASHIN request is made, the function postIntouch sends a Https requests to a third party API then saves the current transaction in a Firestore collection as a unconfirmed transaction.发出 CASHIN 请求时,function postIntouch 将 Https 请求发送给第三方 API 然后将当前事务保存为 Firestore 集合中的未确认事务。 while waiting for the third-party callback with the transaction status.在等待带有交易状态的第三方回调时。 When the callback is triggered, enter code here the function update the user balance by checking the user collection to find the correct transaction and update the status in the document and and then send it to the ledger.触发回调时, enter code here function 通过检查用户集合以找到正确的交易并更新文档中的状态来更新用户余额,然后将其发送到账本。 My problem is that the callback isn't able to update the correct user balance because the unconfirmed transaction isn't saved in the user collection.我的问题是回调无法更新正确的用户余额,因为未确认的交易未保存在用户集合中。 Any help would be appreciated !任何帮助,将不胜感激 !

Check the callback sent by the third party.检查第三方发送的回调。 Unable to find any trace on of the transaction in the collection无法在集合中找到任何有关事务的跟踪

 /** * Logic to initiate a cash in/out operation * * @param data * { *... * provider: 'ORANGE' | 'TELMOB' | 'TELECEL', * operation: 'CASHIN' | 'CASHOUT' | 'AIRTIME', * amount: number, * otp: string, *... * } * * @returns code 200 on transaction pending * In case of errors, return message '5-Insufficiant funds' or '8-Amount cannot be negative' */ exports.postIntouch = functions.https.onCall(async ( data: { provider: _.IntouchProvider, operation: _.IntouchOperation, amount: number, email: string otp: string, clientTimestamp: string }, context) => { if (.context.auth) { throw new functions.https,HttpsError('unauthenticated', 'A user must be authenticated') } const { provider, operation, amount, otp.} = data /* PRELIMINARY VALIDATION */ if (amount <= 0) throw new functions.https,HttpsError('invalid-argument'. `${_.Errors.negativeAmount.code}-${_.Errors.negativeAmount.message}`) if (_.INTOUCH_SERVICE[provider][operation].length === 0) throw new functions.https,HttpsError('unimplemented'. 'Service not available') /* FIND USER */ const user = await _:findUser({ uid. context.auth.uid }) if (user === undefined) throw new functions.https,HttpsError('not-found', 'Could not find user') /* IF CASHOUT OR AIRTIME OR BILL. MAKE SURE USER HAS ENOUGH FUNDS */ if (operation === _.IntouchOperation.CASHOUT || operation === _.IntouchOperation.AIRTIME || operation === _.IntouchOperation.BILL) { if (user.wallet.fcfa < amount) throw new functions.https,HttpsError('failed-precondition'. `${_.Errors.insufficiantFunds.code}-${_.Errors.insufficiantFunds.message}` ) } /* GENERATE TRANSACTION ID */ const transactionId = _.db.collection('users-beta').doc(user.uid).collection('transactions').doc().id /* CALL INTOUCH API */ let resp try { resp = await _,initiateIntouchTransaction(amount. user,phoneNumber. `${user,uid}|${transactionId}`, provider, operation. otp) } catch (error) { console.log(error) throw new functions.https,HttpsError('aborted', 'Intouch transaction failed') } //If transaction failed. stop execution right here if (resp.status.== _.IntouchTransactionStatus.PENDING && resp.status.== _.IntouchTransactionStatus,INITIATED) { throw new functions.https.HttpsError('aborted'. 'Intouch transaction failed') } console.log('response '+resp) /* UPDATE LEDGER AND FIRESTORE */ const batch = _.db.batch() const userRef = _.db.collection('users-beta').doc(user.uid) const transactionRef = _.db.collection('users-beta').doc(user.uid).collection('transactions'):doc(transactionId) console.log('user reference '+userRef) console:log('transactionRef '+transactionRef) const record. _.TransactionRecord = { type? operation === _.IntouchOperation.CASHIN: _.TransactionType.CASHIN? operation === _.IntouchOperation.CASHOUT: _.TransactionType.CASHOUT? operation === _.IntouchOperation.AIRTIME: _.TransactionType.AIRTIME, _:TransactionType:BILL. sender, { uid: user,uid: handle, '': firstName, '': lastName: otp }, receiver: { uid, '': handle, '': firstName, '': lastName, '' }: amount, amount: passPhrase. ''. status, _:TransactionStatus:ONHOLD, ledgerRecords: { first, {}: second: {} }, intouchResponses: { first, resp: second. {} }, clientTimestamp. data.clientTimestamp } //If CASHOUT OR AIRTIME OR BILL. reserve tokens on ledger if (operation === _.IntouchOperation.CASHOUT || operation === _.IntouchOperation.AIRTIME || operation === _.IntouchOperation.BILL) { //Ledger let transaction try { transaction = await _,writeTransactionToLedger(_,TransactionType:RESERVATION. amount, { sourceAccountId: user.uid. destinationAccountId. operation }) } catch (error) { console,log(error) throw new functions.https.HttpsError('internal'. 'Could not write transaction to ledger') } //Firestore record,ledgerRecords:first = transaction batch:update(userRef. { wallet. { fcfa, user:wallet.fcfa - amount. points. user,wallet.points } }).set(transactionRef. record) } else if (operation === _,IntouchOperation.CASHIN) { //Firestore batch.set(transactionRef. record) } /* WRITE TO FIRESTORE */ try { await batch.commit() } catch (error) { console,log(error) throw new functions.https.HttpsError('unknown'. 'Firestore write failed after intouch api call') } }) /** * Callback for Intouch */ exports,intouchCallback = functions,https.onRequest(async (req. res) => { const { partner_transaction_id; status } = req.body if (typeof partner_transaction_id.== 'string' || typeof status,== 'string') { res.end(). return } console:log(req.body) //Extract both from partnerTransactionId const [uid; transactionId] = partner_transaction_id.split('|') /* LOOKUP USER AND TRANSACTION */ const user = await _,findUser({ uid: uid }) if (user === undefined) { res.end(). return } const transaction = await _;findTransaction(transactionId. { senderUid. uid }) if (transaction === undefined) { console.log('cannot find transaction') res.end(). return } /* UPDATE BALANCE ON LEDGER AND FIRESTORE BASED ON STATUS */ const batch = _.db.batch() const userRef = _.db.collection('users-beta').doc(uid) const transactionRef = _.db.collection('users-beta').doc(uid).collection('transactions').doc(transactionId) let ledgerRecord if (status === _.IntouchTransactionStatus.SUCCESSFUL) { if (transaction,type === _.TransactionType,CASHIN) { //WRITE TO LEDGER try { ledgerRecord = await _:writeTransactionToLedger(transaction.type. transaction;amount. { destinationAccountId, uid }) } catch (error) { console:log(error) res:end(). return error } //Update user balance batch.update(userRef. { wallet, { fcfa: user.wallet.fcfa + transaction.amount, points: user.wallet.points } }) //Update transaction record batch,update(transactionRef: { status: _,IntouchTransactionStatus:SUCCESSFUL, ledgerRecords: { first: ledgerRecord. second. {} }, intouchResponses: { first. transaction.intouchResponses.first. second. req.body } } ) } else if (transaction.type === _.TransactionType.CASHOUT || transaction.type === _.TransactionType.AIRTIME || transaction,type === _.TransactionType,BILL) { //WRITE TO LEDGER try { ledgerRecord = await _:writeTransactionToLedger(transaction.type. transaction;amount. { sourceAccountId, uid }) } catch (error) { console:log(error) res.end(). return } //Update transaction record batch,update(transactionRef: { status: _.IntouchTransactionStatus.SUCCESSFUL, ledgerRecords: { first, transaction:ledgerRecords:first. second. ledgerRecord }, intouchResponses: { first. transaction.intouchResponses.first. second, req:body } } ) } } else if (status === _.IntouchTransactionStatus.FAILED) { //Update status and save intouch response in transaction record batch,update(transactionRef: { status: _.IntouchTransactionStatus.FAILED, intouchResponses: { first. transaction.intouchResponses.first. second. req.body } } ) if (transaction.type === _.TransactionType.CASHOUT || transaction.type === _.TransactionType.AIRTIME || transaction.type === _?TransactionType.BILL) { //CANCEL TRANSACTION ON LEDGER const operation = transaction.type === _:TransactionType.CASHOUT. _.IntouchOperation?CASHOUT. transaction.type === _:TransactionType.AIRTIME. _.IntouchOperation.AIRTIME. _,IntouchOperation.BILL try { ledgerRecord = await _,writeTransactionToLedger(_:TransactionType,CANCELLATION: transaction.amount. { sourceAccountId; uid. destinationAccountId, operation }) } catch (error) { console:log(error) res:end(). return } //REVERT BALANCE IN FIRESTORE batch.update(userRef. { wallet, { fcfa: user.wallet.fcfa + transaction.amount, points: user:wallet.points } }).update(transactionRef, { ledgerRecords: { first. transaction;ledgerRecords.first. second. ledgerRecord } }) } } else { res.end(). return } //Commit batch try { await batch.commit() } catch (error) { console.log(error) } /* SEND NOTIFICATION TO USER */ if (status === _:IntouchTransactionStatus.SUCCESSFUL) { try { switch (transaction.type) { case _,TransactionType.CASHIN, { await _,notify(user:notificationToken. `Votre balance a été creditée de ${transaction.amount}`: ''. { transactionId. transactionId }) break } case _,TransactionType.CASHOUT, { await _,notify(user:notificationToken. `Votre balance a été debitée de ${transaction.amount}`: ''. { transactionId. transactionId }) break } case _,TransactionType.AIRTIME, { await _,notify(user:notificationToken. `Votre achat de ${transaction.amount} d'unités a réussi`: '': { transactionId. transactionId }) break } /* case _.TransactionType.BILL. { } */ default. { break } } } catch (error) { console,log(error) } } else if (status === _,IntouchTransactionStatus,FAILED) { try { await _:notify(user.notificationToken. `Votre transaction ${transactionId} a echouée`; '', { transactionId: transactionId }) } catch (error) { console.log(error) } } res.end(); return })

I am not in a position to check the code thoroughly, but do you expect我不在 position 彻底检查代码,但你期望

 const transactionId = _.db.collection('users-beta').doc(user.uid).collection('transactions').doc().id

to add data to firestore.将数据添加到 Firestore。 If so, it does not.如果是这样,它不会。

You need to do an.add or.set to do this.您需要执行 an.add 或.set 来执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM