[Demystifying Firebase (Part-2)] How to setup Firebase authentication in your react native app.
Tags: firebase, reactnative, beginners, javascript
Published: 2024-04-06 15:47:26

## Prerequisites

{% link https://dev.to/suryanshsingh2001/demystifying-firebase-part-1-how-to-setup-firebase-in-react-native-cli-app-256k %}

## 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](https://rnfirebase.io/auth/usage) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56prri2ns8n9vrc47w2e.png)



## Installing the package
First, let's install the React Native Firebase Auth package along with the core app package:
```bash
npm install @react-native-firebase/app @react-native-firebase/auth
```

## Setting up Auth Functions
- It's good practice to create utility functions for auth functions to use them everywhere. 
- Create a folder called Firebase in your root directory and create a new file auth.js. 

![Folder Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6i1wdjdy1r2f56gzp35.png)
Let's start with some basic functions we need.

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

```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.


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

```js
const AuthStackNavigator = () => {
    return (
        <Stack.Navigator>
            <Stack.Screen name="Login" component={LoginScreen} />
        </Stack.Navigator>
    );
}
```

## Handling Authentication State

- Let's open our `App.tsx` We set states for a user and initializing and a function for auth state changed:

```js
const [initializing, setInitializing] = useState(true);
  const [user, setUser] = useState();

  //Handles user state changes
  const onAuthStateChanged = (user: any) => {
    setUser(user);
    if (initializing) setInitializing(false);
  }
```

- Then, we'll use a useEffect hook to subscribe to authStateChanged event handler to track authentication state changes:

```js
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:

```js
 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`

```js
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6jlv9e6vwxsfrkn7jyr.png)

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



```js
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f30obxjhc2tmw59qyeha.png)

Here the basic code for `HomeScreen.jsx`:
```js
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](https://rnfirebase.io/auth/usage)