繁体   English   中英

退出 Firebase React 应用程序时出现“权限不足”错误

[英]“Insufficient permissions” error when signing out of Firebase React app

我的项目在 React/Firebase 中。 我收到“onSnapshot 中未捕获的错误:FirebaseError:缺少权限或权限不足”。 注销时。 有读/写规则,所以我得到错误是有道理的。

我认为这与onSnapshot侦听器如何分离有关,根据: 用户注销时的 Firebase 规则“缺少或不足的权限。 错误:缺少或不足的权限'

我不确定我在分离它们时做错了什么——项目中有 6 个快照侦听器,并且(我认为)我已将其范围缩小到以下提供用户信息的组件:

const UserProvider = props => {
  const [{ user }, setUser] = useState({ user: null });
  const unsubscribeRef = useRef(null);

  useEffect(() => {
    auth.onAuthStateChanged(async user => {
      if (user) {
        const userRef = await createUserProfileDocument(user);

        unsubscribeRef.current = userRef.onSnapshot(snapshot => {
          setUser({ user: { uid: snapshot.id, ...snapshot.data() } });
        });
      }
    });

    return () => unsubscribeRef.current();
  }, []);

  return (
    <UserContext.Provider value={user}>{props.children}</UserContext.Provider>
  );
};

以前,我只是将 unsubscribe 变量直接附加到userRef.onSnapshot位,但没有运气——这就是我在这里尝试useRef的原因。 我想知道在调用signOut 时是否需要以某种方式附加这一点? 似乎没有其他 React/Firebase 应用程序示例使用它。 最后,我不明白为什么,但useEffect中的 return 语句似乎永远无法到达这里。

如果有帮助,这是Authentication组件:

const Authentication = () => {
  const history = useHistory();

  useEffect(() => {
    auth.onAuthStateChanged(async userAuth => {
      if (userAuth) {
        if (history.location.pathname === ROUTES.SIGN_IN)
          history.push(ROUTES.HOME);
      } else {
        history.push(ROUTES.SIGN_IN);
      }
    });
  }, [history]);

  return null;
};

编辑:这些是 Firestore 中的规则:

match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if getUserData().admin == true;
    }

    function getUserData() {
      return get(/databases/$(database)/documents/users/$(request.auth.uid)).data
    }
  }

我不确定这里还有什么相关的。 注销后,用户将被路由回登录页面,该页面不使用数据库中的任何内容。

App() 的结构如下:

function App() {
  return (
    <UserProvider>
      <Router>
        <Authentication />
        <Switch>
          <Route path="/signin" component={SignIn} />
          <Route path="/forgot" component={ForgotPasswordView} />

          <CatalogProvider>
            <Route path="/" component={Main} />
          </CatalogProvider>
        </Switch>
      </Router>
    </UserProvider>
  );
}

并且 Main 包含应用程序工作部分的 rest。

要意识到的一件事是,当用户注销时, onAuthStateChanged会给您一个 null 用户 object。 您的代码似乎无法处理这种情况。

另一件需要意识到的事情是,当用户退出时,如果查询上的任何活动侦听器由于安全规则而变得无效(例如,request.auth 变为空),那么侦听器将因权限错误而被切断。 您应该在退出之前删除依赖于身份验证的查询的所有持久侦听器,或者简单地接受错误将发生并自动删除侦听器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM