通过 onAuthStateChanged 在 Firebase 中查询包含数组的用户数据时遇到无限循环问题
P粉253518620
P粉253518620 2023-08-18 15:16:51
[React讨论组]

我的当前环境是ReactJS 18.2.0,使用Firebase 10运行。

我目前遇到的问题是使用onAuthStateChanged在用户加载或登录页面时查询有关用户的数据。

以下是一个用于处理Firebase Auth的自定义服务的代码片段示例。

所有设置都是上下文的一部分,都是useState。

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

FirebaseFirestoreService.getUserData()函数

const getUserData = async (id) => {
  const docRef = doc(db, "users", id);
  const docSnap = await getDoc(docRef);
  if (docSnap.exists()) {
    return docSnap.data();
  } else {
    return null;
  }
};

这不应该在useEffect中运行,上下文被创建来处理这个问题。

import React, { useState } from "react";
import FirebaseAuthService from "../Services/FirebaseAuthService";

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

  FirebaseAuthService.subscribeToAuthChanges(
    setUser,
    setLoading,
    setRole,
    setEmail,
    setFirstName,
    setIsActive,
    setLastName,
    setLocation,
    setUserID
  );

  return (
    <FirebaseAuth.Provider
      value={{
        user,
        loading,
        role,
        email,
        firstName,
        lastName,
        isActive,
        location,
        userID,
      }}
    >
      {children}
    </FirebaseAuth.Provider>
  );
};

export default FirebaseAuth;

在这个例子中,我缺少一个查询字符串数组的设置函数,然而,以任何方式查询该数组都会导致onAuthStateChanged()不断循环,反复向Firebase发出读取请求。

有没有办法读取数组而不遇到这个问题?

我尝试通过循环遍历数组来避免遇到这个问题,然而,以任何方式查询它都会导致Firebase被反复POST请求。

P粉253518620
P粉253518620

全部回复(1)
P粉978742405

你的循环运行的原因是因为你没有在副作用中设置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;
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号