簡體   English   中英

Firestore 事務順序創建集合和更新文檔

[英]Firestore transaction sequential creation of collections and updating of documents

環境: nodejsfirebase -adminfirestore

數據庫結構(空格): 空間結構

數據庫結構(用戶): 在此處輸入圖片說明

創建新空間(示例):

// init data
const userId = "someUserId";
// Create new space
const spaceRef = await db.collection("spaces").add({ name: "SomeName" });
// Get spaceId
spaceId = spaceRef.id;
// Get user Doc for upate their spaces
const userRef = await db.collection("users").doc(userId);
// Add "spaceId" to user spaces list
userRef.collection("spaces").doc(spaceId).set({ some: "data" });
// Create collection "members" in new space with "userId"
spaceRef.collection("members").doc(userId).set({role: "OWNER"})

問題:我想在單個runTransaction 中執行此代碼,但是當我看到事務僅支持一次讀取和多次更新時,這不適合我,因為我在執行代碼期間獲得了spaceId

為什么我要使用事務:在我的數據結構中,需要創建空間和這個空間的ID在用戶上的存在之間的關系。 如果我們假設在這段代碼的執行過程中發生了錯誤,例如創建了空間,但是在用戶配置文件中沒有添加這個空間,那么這將是我的數據庫結構中的一個致命問題。

與其他數據庫類似,事務解決了這個問題,但我不知道如何用 firestore 來解決這個問題。

也許您知道在這種情況下保護自己免受一致數據影響的更好方法?

實際上,您不需要交易,因為您沒有閱讀文檔。

使用db.collection("users").doc(userId); 您實際上不是在閱讀文檔,只是在“本地”調用doc()方法來創建DocumentReference 此方法不是異步的,因此您不需要使用await 要閱讀文檔,您將使用異步get()方法。


因此,使用批量寫入,將所有掛起的寫入操作原子地提交到數據庫,可以解決問題:

  const userId = 'someUserId';
  const userRef = db.collection('users').doc(userId);

  const spaceRef = firestore.collection('spaces').doc();
  const spaceId = spaceRef.id;

  const writeBatch = firestore.batch();
  writeBatch.set(spaceRef, { name: "SomeName" });
  writeBatch.set(userRef.collection("spaces").doc(spaceId), { some: "data" });
  writeBatch.set(spaceRef.collection("members").doc(userId), {role: "OWNER"});

  await writeBatch.commit();

您應該將此代碼包含在try/catch塊中,如果批量提交失敗,您將能夠在catch塊中處理這種情況,因為知道沒有提交任何寫入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM