我应该构建一个本地数据层/应用程序状态来维护 React Native/Firestore 应用程序中的状态吗? [英] Should I build a local data layer/app state to maintain state in a React Native/Firestore App?

查看:13
本文介绍了我应该构建一个本地数据层/应用程序状态来维护 React Native/Firestore 应用程序中的状态吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

A main selling point of Firestore is the ability to use it as a online/offline source of truth. I'm using it in this way right now: updating the Firestore document directly on an action, then listening to Firestore DB changes and mapping this back to local state. However, relying on this latency compensation and mapping back to local state is not sufficient for quick updates (taps, toggles even with a small document size). For example, toggles will "jitter" as the RN toggle presumptively shifts on tap, and the local state hasn't been updated until it already returns see video example. It appears worse on Android and the problem isn't strictly limited to basic toggles.

  1. Does document size or query result size have a bigger impact on latency compensation? Our document size is very small right now with a worst case ~1000 query result set. We could make the documents 1000x bigger (100kb) and have a query result set of size 1. Update: Testing appears inconsistent here, latency compensation is not ideal in either case
  2. Which of the following other things may impact latency compensation?

    • Using queries with custom indexes. Note: we're not currently reading from cache, we're using the JS SDK
    • Multiple writes. Would multiple writes to the same document make it worse (4 quick writes vs. 2 quick writes). Update: not clear this makes a big difference.
    • Using the native vs. JS module. We're currently using the Firestore Web SDK with an Expo app. Update: switching to native module via React-Native Firestore has no apparent performance improvement.
  3. Is it common for people to build a local data shim layer / local app state with React Native / Firestore apps to help improve local performance speed? Are there any suggested libraries for this?

On app load, mount the listener, and export the result to context to be used through the app

const [user, setUser] = useState();

firebase.firestore().collection(`users/${user.uid}`).onSnapshot(qs => setUser(oldState => {
    const newState = {};
    qs.docChanges().forEach(change => {
      if (change.type === "added" || change.type === "modified") {
        newState[change.doc.id] = {
          docid: change.doc.id,
          ...change.doc.data(),
        };
      } else if (change.type === "removed") {
        delete oldState[change.doc.id];
      }
    });

    return {
      ...oldState,
      ...newState,
    };
  }))

Sample component and function to toggle notifications: (switch is jittery)

const toggleNotifications = (user, value) => {
  firebase.firestore().doc(`users/${user.uid}`).update({
    wantNotifications: value,
  });
};

const TestComponent = () => {
  //gets from context, set in listener mounted on app load
  const { user } = useUserContext();
  return (
    <Switch
      value={user.wantNotifications}
      onValueChange={value => toggleNotifications(user, value)}
    />
  );
};

解决方案

I updated the answer with specific learnings, but after a lot of testing, my biggest general learnings so far are

  • Latency compensation can be very inconsistent even with the same data and environment. Listeners can take time to "warm up", as is mentioned in other questions. It is hard to have a standard metric here.
  • Document size DOES impact latency compensation. Everything else so far is inconclusive.

这篇关于我应该构建一个本地数据层/应用程序状态来维护 React Native/Firestore 应用程序中的状态吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆