【问题标题】:understanding Event Loop using Firebase & React Native使用 Firebase 和 React Native 理解事件循环
【发布时间】:2020-11-09 01:00:39
【问题描述】:

我正在为我的应用构建导航, 我正在尝试为导航提供某些导航条件。 例如:haveFilledForm ? go to screen x : go to screen y 这些条件基于我从 Firebase Live DataBase 获得的 currentUser 对象 我配置了一个带有函数的 database.js 以使用实时数据库,这是我从数据库中获取用户函数:

export const getUser = async (uid) => {
  firebase
    .database()
    .ref("users/" + uid)
    .once("value")
    .then((snap) => {
      console.log(snap);
      return snap;
    });
};

现在,我从一个名为 AppNavigator.js 的主文件管理不同的导航器 在这个文件中,我尝试获取用户信息并根据他从我使​​用firebase.auth() 获得的实时数据库中的道具重定向用户 这是这个页面:

import * as React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { AuthStack } from "./AuthStack";
import { TabNavigator } from "./TabNavigator";
import PersonalInfo from "../screens/Auth/PersonalInfo";
import firebase from "../util/firebase";
import { AppLoading } from "expo";
import { getUser } from "../util/database";

export default class AppNavigator extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      user: "",
      isLoading: true,
      isFilled: false,
      userInfo: {},
    };
  }

  componentDidMount() {
    firebase.auth().onAuthStateChanged(async (user) => {
      if (user) {
        console.log("logged in " + JSON.stringify(user.uid));
        this.setState({ user });
      } else {
        console.log("not logged in");
        this.setState({ user: "" });
        this.setState({ isLoading: false });
      }
      getUser(this.state.user.uid)
        .then((usr) => {
          console.log(usr + " usr");
          this.setState({ userInfo: usr });
          this.setState({ isLoading: false });
        })
        .then(console.log("Imlast"));
    });
  }

  render() {
    if (this.state.isLoading) {
      return <AppLoading />;
    } else {
      return (
        <NavigationContainer>
          {this.state.user ? (
            this.state.userInfo ? (
              <TabNavigator />
            ) : (
              <PersonalInfo />
            )
          ) : (
            <AuthStack />
          )}
        </NavigationContainer>
      );
    }
  }
}

此页面的 console.log 输出为:

logged in "jmC6C5quEFSY0cFBfT8dqJe5E8a2"
Imlast
undefined usr
Object {
  "admin": false,
  "credit": 0,
  "injuries": "",
  "isProfileFilled": true,
  "phone": "",
}

现在我似乎无法理解为什么 Imlast 在用户对象之前打印, 我知道这与 Event Loop 以及 firebase 是异步的事实有关。

那么实现这一目标的正确方法是什么? 最终我的最终目标是根据数据库中的“isProfileFilled”值重定向用户

【问题讨论】:

    标签: firebase react-native firebase-authentication


    【解决方案1】:
    1. Im last 打印在undefined usr 之前的原因是因为.then 接受了一个回调函数,但你传递了一个语句。因此,当 js 解释器检查您的代码时,它会立即执行 console.log,而不是在 promise 解决时等待它被调用。解决方法如下:

    getUser(this.state.user.uid)
      .then((usr) => {
        console.log(usr + " usr");
        this.setState({ userInfo: usr });
        this.setState({ isLoading: false });
      })
      .then(() => console.log("Imlast"));
      //Instead of .then(console.log("Imlast"));
    1. react 中的更改状态是 asynchronous!这意味着当您在下一行调用setState 时,this.state 不能保证等于新状态。 我建议您使用在回调中收到的用户对象,如下所示:getUser(user.uid)。除此之外,将用户两次保存在组件状态(useruserInfo)似乎是多余的。

    2. 不要为用户保存一个空字符串来表示没有用户,只需在ctor中将其初始化为null即可。

    3. 最后要显示基于isProfileFilled 的不同组件,您可以这样做:

      render() {
        const { user, isLoading } = this.state
    
        if (isLoading) {
          return <AppLoading />;
        } else if(!user) {
          return <AuthStack />
        } else {
          return <NavigationContainer>
              {user.isProfileFilled ? <TabNavigator /> : <PersonalInfo />}
            </NavigationContainer>
        }
      }

    【讨论】:

      猜你喜欢
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      • 2021-04-01
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      • 2021-04-28
      • 2018-01-15
      相关资源
      最近更新 更多