0)我有一个HTTP触发器:
exports.checkout = functions.https.onRequest((req, res) => {
1)当用户购买topUp包时更新充值交易:
admin.database().ref('topupTransaction').push(topUpObject)
2)获取用户对象(帐户余额)
admin.database().ref('/users/' + userID).once("value",snap=> {
3)设置新用户对象(使用新帐户余额)
admin.database().ref('/users/' + req.query.userUid).set(topUpObject);
我不确定如何顺序运行所有这些(1,2,3)并将值返回给客户端(0)。打击不应该嵌入承诺。有Promise.all,但在这种情况下如何使用它。
点击“避免嵌套承诺”。当我尝试这样做时:
exports.checkout = functions.https.onRequest((req,res)=> { var nonceFromTheClient = req.body.payment_method_nonce;
var topUpObject = {
amount : parseInt(req.query.topUpPackage),
date : admin.database.ServerValue.TIMESTAMP, // 1525451616097
user : req.query.userUid
};
admin.database().ref('topupTransaction').push(topUpObject)
.then((topUpResult) => {
return admin.database().ref('/users/' + userID).once("value");
}).then((oldUserData)=>{
return admin.database().ref('/users/' + req.query.userUid).set(topUpObject).then((newUserData)=>{
return res.send(newUserData.val());
})
;
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return res.status(500).send(error);
});
更新
使用Promise.all,但部分处理错误:
// Create 2 functions
function asyncFunction1(topUpObject){
// Push top up object to database
admin.database().ref('topupTransaction').push(topUpObject)
.then((response) => {
// Update databse successful (top up transaction)
console.log('Top Up transaction created successfully!', topUpObject);
// return res.redirect(303, response.ref);
return topUpObject;
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return error;
});
}
function asyncFunction2(userID,topUpObject){
// Get the user account balance
console.log('Current User ID: ', userID);
var ref = admin.database().ref('users').child(userID);
admin.database().ref('/users/' + userID).once("value",snap=> {
// do some stuff once
console.log('Current User Data',snap.val());
console.log('Current User balance',snap.val().accountBalance);
var userContents = snap.val();
var currentBalance = userContents.accountBalance;
var updatedBalance = currentBalance + topUpObject.amount;
console.log('Updated Balance',updatedBalance);
userContents.accountBalance = updatedBalance;
/*Current User Data {
accountBalance: 0,
accountCurrency: 'MYR',
createdOn: '2018-05-02T20:42:49Z',
phoneNumber: '+123445555555'
}
*/
admin.database().ref('/users/' + userID).set(userContents).then(snapshot => {
console.log('Updated top up value! for user', topUpObject);
return res.send(topUpObject.amount);
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return error;
});
});
}
// app.post("/checkout", function (req, res) {
exports.checkout = functions.https.onRequest((req, res) => {
var nonceFromTheClient = req.body.payment_method_nonce;
// Use payment method nonce here
// Create Transaction
gateway.transaction.sale({
amount: req.query.topUpPackage,
paymentMethodNonce: nonceFromTheClient,
options: {
submitForSettlement: true
}
},(err, result) => { //TODO: What should we pass back here???
if (err) {
// If top up error (from braintree)
console.log(err.stack);
}else{
// If top up is successful
console.log('Result:',result);
console.log('Top Up Package is: ', req.query.topUpPackage);
var topUpObject = {
amount : parseInt(req.query.topUpPackage),
date : admin.database.ServerValue.TIMESTAMP, // 1525451616097
user : req.query.userUid
};
return Promise.all([asyncFunction1(topUpObject), asyncFunction2(req.query.userUid,topUpObject)]); //TODO: how to pass back res() to client???
}
// Return the error as response
return res.send(err);
});
});
exports.client_token = functions.https.onRequest((req, res) => {
// a token needs to be generated on each request
// so we nest this inside the request handler
// Need to write a function to return a client token,
// and return it back by using the res.send command
console.log('Log customerId',req.query.text);
gateway.clientToken.generate({
// customerId: req.query.text
}, (err, response) => {
// error handling for connection issues
if (err) {
console.log(err.stack);
}else{
clientToken = response.clientToken;
console.log('Log Client token:',clientToken);
return res.send(clientToken);
}
return res.send(err);
});
// return null;
});
答案 0 :(得分:0)
在我的拙见中,有一些事情需要在您的代码中进行微调,如下所示。我在代码中发表了评论。
但请注意,由于我们不知道topUpObject
来自哪里(以及它是什么),因此更难以更准确。如果您分享更多详细信息(完整的云功能代码和数据库结构),我可能会更精确。
admin.database().ref('topupTransaction').push(topUpObject)
.then(topUpResult => {
return admin.database().ref('/users/' + userID).once("value");
})
.then(oldUserData => {
return admin.database().ref('/users/' + req.query.userUid).set(topUpObject);
//Set returns a non-null firebase.Promise containing void
})
.then(() => { //so I don't think you can get the newUserData here
//return res.send(newUserData.val()); <- and therefore you cannot do that here
//But if I understand well you want to send back to the user the topUpObject, so do as follows:
return res.status(200).send(topUpObject); //<- note the addition of status(200) here
})
.catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return res.status(500).send(error);
});