首页  >  问答  >  正文

通过 onAuthStateChanged 在 Firebase 中查询包含数组的用户数据时遇到无限循环问题

<p>我的当前环境是ReactJS 18.2.0,使用Firebase 10运行。</p> <p>我目前遇到的问题是使用onAuthStateChanged在用户加载或登录页面时查询有关用户的数据。</p> <p>以下是一个用于处理Firebase Auth的自定义服务的代码片段示例。</p> <p>所有设置都是上下文的一部分,都是useState。</p> <pre class="brush:js;toolbar:false;">const subscribeToAuthChanges = ( handleAuthChange, setLoadingState, setUserRole, setEmail, setFirstName, setIsActive, setLastName, setLocation, setUserID ) => { onAuthStateChanged(auth, (user) => { if (user) { handleAuthChange(user); FirebaseFirestoreService.getUserData(user.uid).then((data) => { setUserID(user.uid); setUserRole(data.role); setEmail(data.email); setFirstName(data.firstName); setIsActive(data.isActive); setLastName(data.lastName); setLocation(data.location); }); setLoadingState(false); } else { setLoadingState(false); } }); }; </pre> <p>FirebaseFirestoreService.getUserData()函数</p> <pre class="brush:js;toolbar:false;">const getUserData = async (id) => { const docRef = doc(db, "users", id); const docSnap = await getDoc(docRef); if (docSnap.exists()) { return docSnap.data(); } else { return null; } }; </pre> <p>这不应该在useEffect中运行,上下文被创建来处理这个问题。</p>
从“react”导入 React, { useState };
从“../Services/FirebaseAuthService”导入FirebaseAuthService;

const FirebaseAuth = React.createContext({
  用户:空,
  加载:真实,
  角色:“”,
  电子邮件:“”,
  名字:“”,
  是否活跃:假,
  姓氏:“”,
  位置:“”,
  用户ID:“”,
});

导出 const FirebaseAuthProvider = ({ 儿童 }) => {
  const [用户,setUser] = useState(null);
  const [角色,setRole] = useState(null);
  const [电子邮件,setEmail] = useState(“”);
  const [firstName, setFirstName] = useState(“”);
  const [isActive, setIsActive] = useState(false);
  const [lastName, setLastName] = useState("");
  const [位置,setLocation] = useState(“”);
  const [userID, setUserID] = useState(“”);

  const [正在加载,setLoading] = useState(true);

  FirebaseAuthService.subscribeToAuthChanges(
    设置用户,
    设置加载,
    设置角色,
    设置邮箱,
    设置名字,
    设置为活动状态,
    设置姓氏,
    设置位置,
    设置用户ID
  );

  返回 (
    <FirebaseAuth.Provider
      值={{
        用户,
        加载中,
        角色,
        电子邮件,
        名,
        姓,
        活跃,
        地点,
        用户身份,
      }}
    >
      {孩子们}
    </FirebaseAuth.Provider>
  );
};

导出默认 FirebaseAuth;
</前>
<p>在这个例子中,我缺少一个查询字符串读写的设置函数,然而,以任何方式查询该数组都会导致onAuthStateChanged()不断循环,反复向Firebase发出读取请求。
<p>有没有读取解决方案但无法解决这个问题?</p>
<p>我尝试通过循环进行备份来避免遇到这个问题,但是,以任何方式查询它都会导致Firebase被反复POST请求。</p>
P粉253518620P粉253518620400 天前361

全部回复(1)我来回复

  • P粉978742405

    P粉9787424052023-08-19 14:46:23

    你的循环运行的原因是因为你没有在副作用中设置onAuthStateChanged(),请尝试以下操作

    const FirebaseAuth = React.createContext({
      user: null,
      loading: true,
      role: '',
      email: '',
      firstName: '',
      isActive: false,
      lastName: '',
      location: '',
      userID: '',
    });
    
    export const FirebaseAuthProvider = ({ children }) => {
      const [user, setUser] = useState(null);
      const [role, setRole] = useState(null);
      const [email, setEmail] = useState('');
      const [firstName, setFirstName] = useState('');
      const [isActive, setIsActive] = useState(false);
      const [lastName, setLastName] = useState('');
      const [location, setLocation] = useState('');
      const [userID, setUserID] = useState('');
    
      const [loading, setLoading] = useState(true);
    
      useEffect(() => {
        onAuthStateChanged(auth, (user) => {
          setLoading(true);
          if (user) {
            setUser(user);
            FirebaseFirestoreService.getUserData(user.uid).then((data) => {
              setUserID(user.uid);
              setUserRole(data.role);
              setEmail(data.email);
              setFirstName(data.firstName);
              setIsActive(data.isActive);
              setLastName(data.lastName);
              setLocation(data.location);
            });
            setLoadingState(false);
          } else {
            setLoadingState(false);
          }
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
    
      return (
        <FirebaseAuth.Provider
          value={{
            user,
            loading,
            role,
            email,
            firstName,
            lastName,
            isActive,
            location,
            userID,
          }}
        >
          {children}
        </FirebaseAuth.Provider>
      );
    };
    
    export default FirebaseAuth;

    回复
    0
  • 取消回复