我正在構建一個移動應用程式并在某些操作(如 userCreate)上觸發一些 Firebase 函式來執行對第三個服務的 API 呼叫,然后在 Firestore 資料庫中寫入一些內容。
理論上一切正常,但實際上,API 呼叫非常快(即使在冷啟動場景下),但資料庫寫入可能需要幾分鐘才能完成(如果確實如此,我懷疑有時需要太長時間和時間出去)。
由于 API 呼叫作業得很好,資料庫在某些情況下也是如此,我懷疑這僅僅是由于我的異步管理非常差,因為我對 JS 一無所知。
這是與此問題有關的許多示例函式中的兩個,只是為了展示它在我觸發 onCreate 或 HTTPS 函式時發生。
創建函式
const functions = require("firebase-functions");
const axios = require('axios')
// The Firebase Admin SDK to access the Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
// Third party service credentials generation during onCreate request
exports.
buildCredentials = functions.auth.user().onCreate((user) => {
// Request to Third party to generate an Client Access Token
axios({
method: "post",
url: "https://api.ThirdParty.com/api/v1/oauth/token",
data: "client_id=xxx&client_secret=yyy&grant_type=client_credentials&scope=all:all",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
})
.then(function (response) {
//handle success
console.log('new user created: ')
console.log(user.id);
console.log(response.data);
// We write a new document in the users collection with the user ID and the Client Access Token
const db = admin.firestore();
const newUser = {
uid: user.uid,
clientAccessToken: response.data.access_token
};
db.collection('users').doc(user.uid).set(newUser)
.catch(function (error) {
//handle error
console.log(error);
});
})
.catch(function (response) {
//handle error
console.log(response);
});
})
HTTPS onCall 功能
exports.paymentRequest = functions.https.onCall(async (data, context) => {
const clientAccessToken = data.clientAccessToken;
const recipientIban = data.recipientIban;
const recipientName = data.recipientName;
const paymentDescription = data.paymentDescription;
const paymentReference = data.paymentReference;
const productPrice = parseInt(data.productPrice);
const uid = data.uid;
const jsonData = {
"destinations": [
{
"accountNumber": recipientIban,
"type": "iban"
}
],
"amount": productPrice,
"currency": "EUR",
"market": "FR",
"recipientName": recipientName,
"sourceMessage": paymentDescription,
"remittanceInformation": {
"type": "UNSTRUCTURED",
"value": paymentReference
},
"paymentScheme": "SEPA_INSTANT_CREDIT_TRANSFER"
};
(async function(){
response = await axios({
method: "post",
url: "https://api.ThirdParty.com/api/v1/pay",
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${clientAccessToken}`,},
data: jsonData,
})
// We write a the payment request ID in the user's document
const db = admin.firestore();
const paymentRequestID = response.data.id;
db.collection('users').doc(uid).set({
paymentRequestID: paymentRequestID
}, { merge: true })
.catch(function (error) {
//handle error
console.log(error);
});
console.log(response.data)
return response.data
})()
})
我是否在正確的軌道上認為這是一個異步問題?還是 Firebase/Firestore 問題?
謝謝
uj5u.com熱心網友回復:
您沒有回傳異步方法(axios()和set())回傳的承諾,可能會產生云函式的一些“不穩定”行為。
正如您將在Firebase 官方視頻系列中有關“JavaScript Promises”的三個視頻中看到的,您必須在后臺觸發 Cloud Function 中回傳 Promise 或值,以向平臺指示它已完成,并避免它被終止在異步操作完成之前或在作業完成后繼續運行。
以下改編應該可以解決問題(未經測驗):
創建函式:
buildCredentials = functions.auth.user().onCreate((user) => {
// Request to Third party to generate an Client Access Token
return axios({
method: "post",
url: "https://api.ThirdParty.com/api/v1/oauth/token",
data: "client_id=xxx&client_secret=yyy&grant_type=client_credentials&scope=all:all",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
})
.then(function (response) {
//handle success
console.log('new user created: ')
console.log(user.id);
console.log(response.data);
// We write a new document in the users collection with the user ID and the Client Access Token
const db = admin.firestore();
const newUser = {
uid: user.uid,
clientAccessToken: response.data.access_token
};
return db.collection('users').doc(user.uid).set(newUser)
})
.catch(function (response) {
//handle error
console.log(response);
return null;
});
})
可呼叫函式:
exports.paymentRequest = functions.https.onCall(async (data, context) => {
try {
const clientAccessToken = data.clientAccessToken;
const recipientIban = data.recipientIban;
const recipientName = data.recipientName;
const paymentDescription = data.paymentDescription;
const paymentReference = data.paymentReference;
const productPrice = parseInt(data.productPrice);
const uid = data.uid;
const jsonData = {
// ...
};
const response = await axios({
method: "post",
url: "https://api.ThirdParty.com/api/v1/pay",
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${clientAccessToken}`,
},
data: jsonData,
})
// We write a the payment request ID in the user's document
const db = admin.firestore();
const paymentRequestID = response.data.id;
await db.collection('users').doc(uid).set({
paymentRequestID: paymentRequestID
}, { merge: true })
console.log(response.data)
return response.data
} catch (error) {
// See https://firebase.google.com/docs/functions/callable#handle_errors
}
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/415661.html
標籤:
下一篇:Flutter-我正在為我的電子商務應用程式創建一個購物車,并希望將產品從購物車集合轉移到firestore中的訂單集合
