簡體   English   中英

如何優化這個 firebase 實時數據庫請求?

[英]How to optimize this firebase real time database requests?

我正在構建一個瑣事游戲。

用戶成功完成一個關卡后,我調用服務器請求打開下一個關卡。 除了打開下一個關卡,我還調用了一個更新用戶分數的服務器請求。

您是否有關於如何優化它的建議,以便花費更少的時間,也許取出一個將更新兩個字段的服務器請求?

我使用 Firebase 以及它在實時數據庫中的外觀:

在此處輸入圖像描述

這里有一些代碼:

如果答案正確:

const onAnswerPressedHandler = async answer => {
    const rightAnswer = answer === selectedLevel.rightAnswer;
    dispatch(setShowLoader(true));
    if (rightAnswer) {
      if (isNotLastLevel) {
        await updateRank();
        await unlockNextLevelIfExist();
      } else if (isNotLastWorld) {
        await updateRank();
        await unlockNextWorldIfExist();
      } else {
        await updateRank();
        navigation.pop(3);
      }
    }

    dispatch(setShowLoader(false));
  };

更新 firebase 中的排名:

export const updateUserScoreAndRank = (score, rank) => new Promise(async (resolve, reject) => {
  try {
    await database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('score')
      .set(score);
    await database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('rank')
      .set(rank);
    resolve();
  } catch (e) {
    reject(e);
    console.log(e);
  }
});

解鎖下一個級別:

export const setLevelPassed = (worldIndex, levelIndex) => new Promise(async (resolve, reject) => {
  try {
    await database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_GAME_DETAILS)
      .child(firebaseRefs.CURRENT_USER_GAME_DATA)
      .child(worldIndex.toString())
      .child(firebaseRefs.GAME_QUESTIONS)
      .child(levelIndex.toString())
      .child(firebaseRefs.IS_LOCKED)
      .set(false);
    resolve();
  } catch (e) {
    reject(e);
    console.log('setLevelPassed', e);
  }
});

知道如何改進請求嗎?

您在這里使用了兩個單獨的await調用:

export const updateUserScoreAndRank = (score, rank) => new Promise(async (resolve, reject) => {
  try {
    await database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('score')
      .set(score);
    await database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('rank')
      .set(rank);
    resolve();
  } catch (e) {
    reject(e);
    console.log(e);
  }
});

這意味着調用是按順序執行的,只有在兩者都完成后,方法返回的 promise 才會解析。

但是這兩個調用不以任何方式相互依賴,因此您可以並行執行它們,這樣第二個調用就不會等待第一個調用完成。 這樣做,您還可以嘗試自定義 promise 並從Promise.all()返回一個:

export const updateUserScoreAndRank = (score, rank) => {
  return Promise.all([
    database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('score')
      .set(score),
    database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .child('rank')
      .set(rank);
  ]);
});

對於另一個簡化,您可以使用單個多位置更新,而不是兩個數據庫調用。 這不會再產生顯着的性能差異,因為 Firebase 已經通過單個連接對請求進行管道傳輸,但它會使代碼更短一些,並且更新是原子的。

export const updateUserScoreAndRank = (score, rank) => {
  return database()
      .ref(firebaseRefs.USERS_REF)
      .child(auth().currentUser.uid)
      .child(firebaseRefs.CURRENT_USER_DETAILS)
      .update({ rank, score })
});

暫無
暫無

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

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