Demystifying Firebase (Part-2)

June 20, 2024 (5mo ago)

Introduction

In my previous post, we covered how to set up Firebase in your React Native CLI App. Firebase Auth offers several authentication providers, including email/password, phone number authentication, Google sign-in, etc. For this series, we'll be using React Native Firebase for our project.

To keep things simple, we'll implement Anonymous Authentication in our app. Let's dive in!

Firebase Console

Activate Anonymous Authentication or your preferred authentication provider from your firebase console.

Firebase Console

Installing the package

First, let's install the React Native Firebase Auth package along with the core app package:

npm install @react-native-firebase/app @react-native-firebase/auth

Setting up Auth Functions

Folder Structure Let's start with some basic functions we need.

Here's the code for Firebase/auth.js:

import Auth from '@react-native-firebase/auth';
 
// Get the auth settings
export const getAuthSettings = () => {
    const authSettings =  Auth().settings;
    return authSettings;
}
 
// Get the current signed in user
export const getCurrentUser = () => {
    const currentUser = Auth().currentUser;
    return currentUser || null;
}
 
 
// Sign in anonymously function
export const signInAnonymously = async () => {
    try {
        await Auth().signInAnonymously();
 
    } catch (error) {
        console.error(error);
    }
}
 
// Sign out function
export const signOut = async () => {
    try {
        await Auth().signOut();
    } catch (error) {
        console.error(error);
    }
}

Separate Screens Based Authentication

I'm using React Navigation, with separate navigators for logged-in users (MainStackNavigator) and those who are not (AuthStackNavigator), but you may use the same navigation and keep screens separate instead.

const MainStackNavigator = () => {
    return (
        <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
        </Stack.Navigator>
    );
    }
const AuthStackNavigator = () => {
    return (
        <Stack.Navigator>
            <Stack.Screen name="Login" component={LoginScreen} />
        </Stack.Navigator>
    );
}

Handling Authentication State

const [initializing, setInitializing] = useState(true);
  const [user, setUser] = useState();
 
  //Handles user state changes
  const onAuthStateChanged = (user: any) => {
    setUser(user);
    if (initializing) setInitializing(false);
  }
useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber;
  }, []);

Finally, we can separate our login screens from home screens based on the user's state like this:

 return (
    <NavigationContainer>
      {user ? <MainStackNavigator /> : <AuthStackNavigator />}
    </NavigationContainer>
  );

This ensures that users are directed to the appropriate screens based on their authentication status.

Here is complete code for App.tsx

import {useEffect, useState} from 'react';
 
import {NavigationContainer} from '@react-navigation/native';
import MainStackNavigator from './routes/MainStackNavigator';
import AuthStackNavigator from './routes/AuthStackNavigator';
import auth from '@react-native-firebase/auth';
 
const App = () => {
  const [initializing, setInitializing] = useState(true);
  const [user, setUser] = useState();
 
  //Handles user state changes
  const onAuthStateChanged = (user: any) => {
    setUser(user);
    if (initializing) setInitializing(false);
  };
 
  useEffect(() => {
    const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
    return subscriber;
  }, []);
 
  if (initializing) return null;
 
  return (
    <NavigationContainer>
      {user ? <MainStackNavigator /> : <AuthStackNavigator />}
    </NavigationContainer>
  );
};
 
export default App;

Login Screen

Login Screen

In my LoginScreen.jsx, I'll use signInAnonymously function to sign in into HomeScreen.jsx. Here's the basic code for Login Screen:

import {View, Text, Button} from 'react-native';
import {signInAnonymously} from '../Firebase/auth';
 
const LoginScreen = ({navigation}) => {
  const handleLogin = async () => {
    await signInAnonymously();
    console.log('User Logged In');
  };
 
  return (
    <View style={{flex:1, alignItems: "center", margin: 10}}>
      <Text style={{fontSize: 20, color: "black", marginBottom: 20}}>Login Screen</Text>
      <Button title="Click To Login" onPress={handleLogin} />
    </View>
  );
};
 
export default LoginScreen;
 

On logging in, we'll be directly taken to our Home Screen. If you try to press back when logged in, you won't be able to go back to the login screens.

Home Screen

Here the basic code for HomeScreen.jsx:

import {View, Text, Button} from 'react-native';
import React from 'react';
import {signOut} from '../Firebase/auth';
 
const HomeScreen = ({navigation}) => {
  const handleLogout = async () => {
    await signOut();
    console.log('User Logged Out');
  };
  return (
    <View style={{flex: 1, alignItems: 'center'}}>
      <Text
        style={{
          color: 'black',
          margin: 10,
          padding: 10,
          fontSize: 20,
          fontWeight: 'bold',
        }}>
        Demystify Firebase
      </Text>
 
      <View style={{margin: 10, padding: 10, flexDirection: 'row', columnGap: 10}}>
        <Button
          title="Go to Profile"
          onPress={() => navigation.navigate('Profile')}
          color={'#f194ff'}
        />
 
        <Button title="Logout" onPress={handleLogout} />
      </View>
    </View>
  );
};
 
export default HomeScreen;

That wraps up our implementation of a simple authentication flow into our app using Firebase Auth.

If you're eager to explore more authentication-related topics, drop a comment below! Your feedback helps shape the content you want to see. Let's dive deeper into authentication together!

Source: React Native Firebase