Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在reactjs中避免不必要的Firestore读取?_Reactjs_Firebase_Google Cloud Firestore - Fatal编程技术网

如何在reactjs中避免不必要的Firestore读取?

如何在reactjs中避免不必要的Firestore读取?,reactjs,firebase,google-cloud-firestore,Reactjs,Firebase,Google Cloud Firestore,免责声明:我希望我的描述一针见血,因为我在这个问题上花了很多时间。请在评论中给我反馈,以改进我的问题,这样你就有足够的信息给我一个好的答案。我创建这个应用程序是为了支持科罗纳疫苗中心作为一个慈善项目,但我没有得到报酬,我尽量避免为firestore阅读花费金钱。因此,我想减少它们 我有两个用ReactJS构建的web应用程序: 用户可以生成登记单 管理员可以将用户签入 1。应用程序只有firestore写入。每个用户一次写入。我将不涉及该应用程序的更多细节,因为它不会有问题 二,。当每个用户签

免责声明:我希望我的描述一针见血,因为我在这个问题上花了很多时间。请在评论中给我反馈,以改进我的问题,这样你就有足够的信息给我一个好的答案。我创建这个应用程序是为了支持科罗纳疫苗中心作为一个慈善项目,但我没有得到报酬,我尽量避免为firestore阅读花费金钱。因此,我想减少它们


我有两个用ReactJS构建的web应用程序:

  • 用户可以生成登记单
  • 管理员可以将用户签入
  • 1。应用程序只有firestore写入。每个用户一次写入。我将不涉及该应用程序的更多细节,因为它不会有问题

    二,。当每个用户签入时,应用程序有1次写入,我对读取有问题,因为应用程序currentyl每天很快达到50000次免费读取。我只有3.000个用户(蓝色线表示读取,紫色线表示写入):

    管理员应用程序有三个视图:
    CheckInView
    UserArchive
    UserView
    。该应用程序使用Firestore数据库和一个
    用户
    集合。我构建应用程序只是为了正常工作,现在我想修改代码以避免对firestore应用程序进行不必要的读取

    对于
    CheckInView
    我需要
    .onSnapshot()
    ,这样管理员就不需要手动刷新页面并自动查看新用户。它只读取未签入的用户(
    。其中(“checkedin”,“==”,null)

    UserArchive
    应显示已签入的所有用户(
    。其中(“checkedin”,“!=”,null)
    )。它有一个用于筛选/搜索特定用户的输入字段。每天大约有200-300个用户,最多有10个用户没有同时登记。这意味着每天有200-300名新用户。因此,每天有200-300多人阅读

    对于
    UserView
    我正在再次阅读,但只有一个用户。我真的不知道为什么我的应用程序这么难扩展读取。当您从
    UserView
    返回
    UserArchive
    时,可能会发生这种情况,因为它一次又一次地获取所有用户

    我可以在
    UserArchive
    中从
    .onSnapshot()
    切换到
    .get()
    ,但我不确定这个问题是否解决了。也许不是

    也许有人比我更有firestore读取方面的经验,可以检查我的代码,并看到这么多读取的问题

    这是我的mutch精简代码,具有基本功能:

    import { useEffect, useState } from "react";
    import { BrowserRouter as Router, Switch, Route, Link } from "react-router-dom";
    import firebase from "./firebase";
    
    function App() {
      return (
        <div className="App">
          <Router>
            <Switch>
              <Route exact path="/checkin" component={CheckInView} />
              <Route exact path="/userview/:udi" component={UserView} />
              <Route exact path="/userarchive" component={UserArchive} />
            </Switch>
          </Router>
        </div>
      );
    }
    
    export default App;
    
    export const CheckInView = () => {
      const [users, setUsers] = useState([]);
    
      useEffect(() => {
        const unsubscribe = firebase
          .firestore()
          .collection("users")
          .where("infected", "==", null)
          .onSnapshot((fetchedUsers) => {
            setUsers(fetchedUsers.docs.map((user) => user.data()));
          });
    
        return () => {
          unsubscribe();
        };
      }, [setUsers]);
    
      return (
        <div>
          <Link to="/userarchive">- Archive</Link>
          {users.map((user) => (
            <div key={user.uid}>
              <Link to={`/userview/${user.uid}`}>{user.name}</Link>
            </div>
          ))}
        </div>
      );
    };
    
    const UserArchive = () => {
      const [users, setUsers] = useState([]);
      const [search, setSearch] = useState("");
    
      useEffect(() => {
        const unsubscribe = firebase
          .firestore()
          .collection("users")
          .where("infected", "!=", null)
          .onSnapshot((fetchedUsers) => {
            setUsers(fetchedUsers.docs.map((user) => user.data()));
          });
    
        return () => {
          unsubscribe();
        };
      }, [setUsers]);
    
      return (
        <div>
          <Link to="/checkin">- CheckIn</Link>
          <input
            type="text"
            value={search}
            placeholder="Search..."
            onChange={(e) => setSearch(e.target.value)}
          />
          {users
            .filter((e) => e.name.toLowerCase().includes(search.toLowerCase()))
            .map((user) => (
              <div key={user.uid}>
                <Link to={`/userview/${user.uid}`}>{user.name}</Link>
              </div>
            ))}
        </div>
      );
    };
    
    const UserView = ({ match }) => {
      const [user, setUser] = useState();
    
      useEffect(() => {
        const unsubscribe = firebase
          .firestore()
          .collection("users")
          .doc(match.params.uid)
          .onSnapshot((user) => {
            setUser(user.data());
          });
    
        return () => {
          unsubscribe();
        };
      }, [setUser, match.params.uid]);
    
      return (
        <>
          <div>{user !== undefined ? user.name : "No Valid User."}</div>
          <Link to="/checkin">Back</Link>
        </>
      );
    };
    
    
    从“react”导入{useffect,useState};
    从“react Router dom”导入{BrowserRouter as Router,Switch,Route,Link};
    从“/firebase”导入firebase;
    函数App(){
    返回(
    );
    }
    导出默认应用程序;
    导出常量CheckInView=()=>{
    const[users,setUsers]=useState([]);
    useffect(()=>{
    const unsubscribe=firebase
    .firestore()
    .收集(“用户”)
    。其中(“已感染”,“==”,null)
    .onSnapshot((fetchedUsers)=>{
    setUsers(fetchedUsers.docs.map((user)=>user.data());
    });
    return()=>{
    取消订阅();
    };
    },[setUsers]);
    返回(
    -档案馆
    {users.map((用户)=>(
    {user.name}
    ))}
    );
    };
    constuserarchive=()=>{
    const[users,setUsers]=useState([]);
    const[search,setSearch]=useState(“”);
    useffect(()=>{
    const unsubscribe=firebase
    .firestore()
    .收集(“用户”)
    。其中(“已感染”,“!=”,空)
    .onSnapshot((fetchedUsers)=>{
    setUsers(fetchedUsers.docs.map((user)=>user.data());
    });
    return()=>{
    取消订阅();
    };
    },[setUsers]);
    返回(
    -签到
    setSearch(e.target.value)}
    />
    {用户
    .filter((e)=>e.name.toLowerCase().includes(search.toLowerCase()))
    .map((用户)=>(
    {user.name}
    ))}
    );
    };
    const UserView=({match})=>{
    const[user,setUser]=useState();
    useffect(()=>{
    const unsubscribe=firebase
    .firestore()
    .收集(“用户”)
    .doc(匹配.params.uid)
    .onSnapshot((用户)=>{
    setUser(user.data());
    });
    return()=>{
    取消订阅();
    };
    },[setUser,match.params.uid]);
    返回(
    {user!==未定义?user.name:“无有效用户。”}
    返回
    );
    };
    
    一个
    .onSnapshot()
    添加到
    App
    组件中,并将其传递给所有视图,并根据我的要求对其进行过滤,这是一个好主意吗

    • users.fiter(e=>e.checkedin==true)
      用于用户存档
    • users.fiter(e=>e.checkedin==false)
      用于checkenView
    • users.fiter(e=>e.uid==march.params.uid)
      用于用户视图

    您好,读取的原因是,每次组件渲染时,都会运行
    效果
    函数

    例如

    const UserView = ({ match }) => {
      const [user, setUser] = useState();
    
      useEffect(() => {
        const unsubscribe = firebase
          .firestore()
          .collection("users")
          .doc(match.params.uid)
          .onSnapshot((user) => {
            setUser(user.data());
          });
    
        return () => {
          unsubscribe();
        };
      });
    
      return (
        <>
          <div>{user !== undefined ? user.name : "No Valid User."}</div>
          <Link to="/checkin">Back</Link>
        </>
      );
    };
    

    通过以上更改,仅当安装的组件

    useffect
    钩子还依赖于
    match.params.uid
    时,效果才会运行,因此最好在依赖项数组中传递它
    [match.params.uid]
    很抱歉,这是我的问题。在我的real app中,所有useEffects都取决于相关的
    setUsers
    match.params.uid
    。我更新了我的代码。如果是这样,我认为您应该登录effect函数来检测完整的端到端流调用了多少次。通过这样做,您将检测并部分调用服务most
    useEffect(() => {
        const unsubscribe = firebase
          .firestore()
          .collection("users")
          .doc(match.params.uid)
          .onSnapshot((user) => {
            setUser(user.data());
          });
    
        return () => {
          unsubscribe();
        };
      }, []);