简体   繁体   English

如何优化这个 firebase 实时数据库请求?

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

I'm building a trivia game.我正在构建一个琐事游戏。

After the user successfully completes a Level, I calling a server request that opens the next Level.用户成功完成一个关卡后,我调用服务器请求打开下一个关卡。 In addition to opening the next Level, I calling one more server request that updates the user's score.除了打开下一个关卡,我还调用了一个更新用户分数的服务器请求。

Do you have a recommendation on how to optimize it, so that it takes less time, maybe take out one server request that will update the two fields?您是否有关于如何优化它的建议,以便花费更少的时间,也许取出一个将更新两个字段的服务器请求?

I use Firebase and this how it looks inside realtime database:我使用 Firebase 以及它在实时数据库中的外观:

在此处输入图像描述

Here some code:这里有一些代码:

If the answer is correct:如果答案正确:

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));
  };

Updating rank in firebase:更新 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);
  }
});

Unlocking next Level:解锁下一个级别:

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);
  }
});

Any idea how to improve the requests?知道如何改进请求吗?

You're using two separate await calls here:您在这里使用了两个单独的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);
  }
});

This means the calls are executed sequentially, and only once both are done does the promise returned by the method resolve.这意味着调用是按顺序执行的,只有在两者都完成后,方法返回的 promise 才会解析。

But the two calls don't depend on each other in any way, so you can execute them in parallel so that the second one isn't waiting for the first one to be finished.但是这两个调用不以任何方式相互依赖,因此您可以并行执行它们,这样第二个调用就不会等待第一个调用完成。 Doing this, you can also get try of the custom promise and return the one from Promise.all() :这样做,您还可以尝试自定义 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);
  ]);
});

For another simplification you can use a single multi-location update, instead of two database calls.对于另一个简化,您可以使用单个多位置更新,而不是两个数据库调用。 This won't make a significant performance difference anymore, since Firebase already pipelines the requests over a single connection, but it will make the code a bit shorter, and the updates atomic.这不会再产生显着的性能差异,因为 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