React Native Firebase logout function doesn't work after login based on user type

Viewed 32

I'm building a react native application with Expo and Firebase. I have two type of users, gymnasts and coaches. At first I had a basic logout function which worked without any issues. After I've added the functionality of showing differents screens based on the type of user (gymnast or coach) that's logged in, the logout function doesn't do anything anymore.

When I refresh the expo app I get a render error:

null is not an object (evaluating '_firebase.firebase.auth().currentUser.uid'),

but I don't get any feedback when I click on the logout button.

const ProfileCoach = ({ navigation, route }) => {
  const [users, setUsers] = useState([]);
  const usersRef = firebase
    .firestore()
    .collection("users")
    .where("uid", "==", firebase.auth().currentUser.uid);

  const logout = () => {
    firebase.auth().signOut();
  };

  useEffect(() => {
    usersRef.onSnapshot((querySnapshot) => {
      const users = [];
      querySnapshot.forEach((doc) => {
        const { username, role, club, email } = doc.data();
        users.push({
          id: doc.id,
          username,
          role,
          club,
          email,
        });
      });
      setUsers(users);
    });
  }, []);

  return (
    <SafeAreaView style={styles.mainView}>
      <View style={styles.mainView}>
        <FlatList
          data={users}
          keyExtractor={(item) => item.id}
          renderItem={({ item }) => (
            <View>
              <Text style={styles.Header}>Hi, {item.username}</Text>
              <Text style={styles.Text}>You are a {item.role}</Text>
              <Text style={styles.Text}>Your club is {item.club}</Text>
            </View>
          )}
        ></FlatList>
        <View>
          <TouchableOpacity style={styles.Button} onPress={logout}>
            <Text style={styles.ButtonText}>Logout</Text>
          </TouchableOpacity>
        </View>
      </View>
    </SafeAreaView>
  );
};

export default ProfileCoach;

export default function App() {
  const Stack = createStackNavigator();
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const Tab = createBottomTabNavigator();
  const [userRole, setUserRole] = useState("");

  useEffect(() => {
    firebase.auth().onAuthStateChanged(async (user) => {
      if (user) {
        setIsLoggedIn(true);
        const userDocSnap = await firebase
          .firestore()
          .collection("users")
          .doc(user.uid)
          .get();

        if (userDocSnap.exists) {
          const userData = userDocSnap.data();
          setUserRole(userData.role);
        } else {
          console.log("user document is missing");
        }
      } else {
        setIsLoggedIn(false);
      }
    });
  }, []);


  if (userRole === "Gymnast") {
    return (
     <NavigationContainer>

1 Answers

The error you get actually seems to indicate that the user is signed out:

null is not an object (evaluating '_firebase.firebase.auth().currentUser.uid'),

If no user is signed in, _firebase.firebase.auth() is going to be null, leading to the "null is not an object" error.

To prevent this error from happening, you should only initialize usersRef once the user is signed in. So something like:

useEffect(() => {
  firebase.auth().onAuthStateChanged(async (user) => {
    if (user) {
      usersRef = firebase
        .firestore()
        .collection("users")
        .where("uid", "==", firebase.auth().currentUser.uid);
      ...
Related