我使用 Firebase 作為 iOS 應用程式的后端,但不知道如何通過他們的 Cloud Functions 構建批量寫入。
我的 Firestore 中有兩個系列,飲料和顧客。每個新飲料和每個新客戶都分配了一個userId與當前登錄用戶的 uid 對應的屬性。這userId與對 Firestore 的查詢一起使用,以僅獲取連接到登錄用戶的飲料和客戶,如下所示:Firestore.firestore().collection("customers").whereField("userId", isEqualTo: Auth.auth().currentUser.uid)
用戶可以匿名登錄,也可以匿名訂閱。問題是如果他們注銷,就無法重新登錄到相同的匿名 uid。uid 也appUserID與 RevenueCat SDK 一起存盤,因此我仍然可以訪問它,但由于我無法使用 uid 將用戶重新登錄到他們的匿名帳戶,這是幫助用戶訪問其資料的唯一方法恢復購買是將userId他們的資料欄位從舊的uid更新到新的uid。這就是需要批量寫入的地方。
總的來說,我對編程比較陌生,但在 Cloud Functions、JavaScript 和 Node.js 方面我非常新鮮。不過,我在網上四處游蕩,并認為我找到了一個解決方案,我創建了一個可呼叫的云函式,并使用資料物件發送新舊用戶 ID,使用舊用戶 ID 查詢檔案的集合并將其userId欄位更新為新的。不幸的是,它不起作用,我不知道為什么。
這是我的代碼的樣子:
// Cloud Function
exports.transferData = functions.https.onCall((data, context) => {
const firestore = admin.firestore();
const customerQuery = firestore.collection('customers').where('userId', '==', `${data.oldUser}`);
const drinkQuery = firestore.collection('drinks').where('userId', '==', `${data.oldUser}`);
const customerSnapshot = customerQuery.get();
const drinkSnapshot = drinkQuery.get();
const batch = firestore.batch();
for (const documentSnapshot of customerSnapshot.docs) {
batch.update(documentSnapshot.ref, { 'userId': `${data.newUser}` });
};
for (const documentSnapshot of drinkSnapshot.docs) {
batch.update(documentSnapshot.ref, { 'userId': `${data.newUser}` });
};
return batch.commit();
});
// Call from app
func transferData(from oldUser: String, to newUser: String) {
let functions = Functions.functions()
functions.httpsCallable("transferData").call(["oldUser": oldUser, "newUser": newUser]) { _, error in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
print(code)
print(message)
print(details)
}
}
}
}
這是來自 Cloud Functions 日志的錯誤訊息:
Unhandled error TypeError: customerSnapshot.docs is not iterable
at /workspace/index.js:22:51
at fixedLen (/workspace/node_modules/firebase-functions/lib/providers/https.js:66:41)
at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:385:32
at processTicksAndRejections (internal/process/task_queues.js:95:5)
據我了解customerSnapshot,這是一種叫做 Promise 的東西,我猜這就是為什么我不能迭代它。到目前為止,我對我的稀疏知識來說太深了,不知道如何處理查詢回傳的這些 Promise。
我想我可以強迫用戶在訂閱之前創建一個登錄名,但既然我已經走到了這一步,那感覺就像是一個懦夫的出路。我寧愿兩個選項都可用并做出決定,而不是走上強制的道路。另外,如果我弄明白了,我會學習更多的 JavaScript!
非常感謝任何和所有幫助!
編輯:
解決方案:
// Cloud Function
exports.transferData = functions.https.onCall(async(data, context) => {
const firestore = admin.firestore();
const customerQuery = firestore.collection('customers').where('userId', '==', `${data.oldUser}`);
const drinkQuery = firestore.collection('drinks').where('userId', '==', `${data.oldUser}`);
const customerSnapshot = await customerQuery.get();
const drinkSnapshot = await drinkQuery.get();
const batch = firestore.batch();
for (const documentSnapshot of customerSnapshot.docs.concat(drinkSnapshot.docs)) {
batch.update(documentSnapshot.ref, { 'userId': `${data.newUser}` });
};
return batch.commit();
});
uj5u.com熱心網友回復:
正如您已經猜到的那樣,該呼叫customerQuery.get()回傳了一個承諾。
為了理解你需要什么,你應該首先在這里熟悉 Promise 的概念:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
對于您的用例,您可能最終會使用then回呼:
customerQuery.get().then((result) => {
// now you can access the result
}
或者通過使用以下await陳述句使方法呼叫同步:
const result = await customerQuery.get()
// now you can access the result
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/415666.html
標籤:
