Build an Anonymous Chat App with React Native and Firebase

Build an Anonymous Chat App with React Native and Firebase

he year 2020 has seen a lot of changes in the React Native world:

  • community adoption of React Hooks in React Native apps has increased
  • the docs have a new domain
  • the popular navigation library react-navigation adopted a declarative and component-based approach to implement navigation in an app
  • react-native-firebase, the go-to package to use Firebase SDK, released its sixth version

In this tutorial, I am going to walk you through building a simple chat application that a user can log in to without credentials and straightaway enter a chat room using the anonymous sign-in method provided by Firebase.

The purpose of this tutorial is to get you familiar with all the latest updates in React Native world and its libraries like react-navigation and react-native-firebase that are used often. If you wish to add a new feature that is not covered in this tutorial, feel free to do that and follow along at your own pace.

Requirements

The following requirements will make sure you have a suitable development environment:

  • Node.js above 10.x.x installed on your local machine
  • JavaScript/ES6 basics
  • watchman the file watcher installed
  • react-native-cli installed through npm or access via npx

For a complete walkthrough on how you can set up a development environment for React Native, you can go through official documentation here.

Also, do note that the following tutorial is going to use the react-native version 0.61.5. Please make sure you are using a version of React Native above 0.60.x.

Getting started with the Crowdbotics App Builder

To generate a new React Native project you can use the react-native cli tool. Or, if you want to follow along, I am going to generate a new app using the Crowdbotics App Builder.

Register either using your GitHub credentials or your email. Once logged in, you can click the Create App button to create a new app. The next screen is going to prompt you as to what type of application you want to build. Choose Mobile App.

Enter the name of the application and click the button Create App. After you link your GitHub account from the dashboard, you are going to have access to the GitHub repository for the app. This repo generated uses the latest react-native version and comes with built-in components and complete examples that can be the base foundation for your next app.

You can now clone or download the GitHub repo that is generated by the Crowdbotics app building platform. Once you have access to the repo on your local development environment, make sure to navigate inside it. You will have to install the dependencies for the first time using the command yarn install. Then, to make it work on the iOS simulator/devices, make sure to install pods using the following commands from a terminal window.

That’s it. It’s a three-step process. Now, let us get back to our tutorial.

Setting up navigation

To start, create a new React Native project and install the dependencies to set up and use the react-navigation library.

From React Native 0.60.x and higher, linking is automatic so you don’t need to run react-native link.

To finalize the installation, on iOS, you have to install pods. (Note: Make sure you have Cocoapods installed.)

Similarly, on Android, open android/app/build.gradle and add the following two lines in the dependencies section:

Lastly, to save the app from crashing in a production environment, add the following line in index.js.

That’s it for setting up the react-navigation library.

Adding vector icons

What is a mobile app without the use of icons? One famous library created by Oblador is called react-native-vector-icons. This library has a set of icons bundled from AntDesign, FontAwesome, Ionicons, MaterialIcons, and so on.

In this section, let us install that. Open up a terminal window and run the command yarn add react-native-vector-icons to install the library.

After the library is installed, for iOS, copy the following list of fonts inside ios/rnAnonChatApp/Info.plist.

Then, open ios/Podfile and add the following:

Open a terminal window to install pods.

For Android, make sure you add the following in android/app/build.gradle:

That’s it to set up a vector icons library in a React Native project.

Build two screens

Before you proceed to set up a navigation pattern in this app to switch between the different screens, let us create two different screens first.

Create a new file called src/screens/Login.js and add the following code snippet. For now, it going to display a message and a button. This screen is going to be displayed when the user isn’t authenticated to enter the app and access a chat room.

Next, create another file in the same directory called ChatRoom.js with the following code snippet:

For now, the above screen component is going to display a text message, but later it is going to contain many functionalities and features for the user to interact with.

Setting up two separate navigators

Start by creating a new directory src/navigation/ and inside it, two new files:

  • SignInStack.js
  • SignOutStack.js

Both of these files are self-explanatory by their names. Their functionality is going to contain screens related to the state of the app. For example, the SignInStack.js is going to have a stack navigator that has screen files (such as ChatRoom.js) that a user can only access after they are authenticated.

What is a stack navigator?

A Stack Navigator provides the React Native app with a way to transition between different screens, similar to how the navigation in a web browser works. It pushes or pops a screen when in the navigational state.

Now that you have an idea of what exactly a stack navigator is, understand what NavigationContainer and createStackNavigator do.

  • NavigationContainer is a component that manages the navigation tree. It also contains the navigation state and has to wrap all the navigator’s structure.
  • createStackNavigator is a function used to implement a stack navigation pattern. This function returns two React components: Screen and Navigator, which help us configure each component screen.

Open SignInStack.js and add the following code snippet:

In the above snippet, there are two required props with each Stack.Screen. The prop name refers to the name of the route, and the prop component specifies which screen to render at that particular route.

Similarly, in the file SignOutStack.js, add the following code snippet:

This is how navigators are defined declaratively using version 5 of react-navigation. It follows a more component-based approach, similar to that of react-router in web development.

Before we begin to define a custom authentication flow (since this version of react-navigation does not support a SwitchNavigator like previous versions), let us add the Firebase SDK. Using the Firebase functions, you can then easily implement an authentication flow to switch between the two stack navigators.

try our app estimate calculator CTA image

Adding Firebase SDK

If you have used react-native-firebase version 5 or below, you may have noticed that it was a monorepo that used to manage all Firebase dependencies from one module.

Version 6 brings you the option to only install those Firebase dependencies required for features that you want to use. For example, in the current app, you are going to start by adding the auth package. Also, do note that the core module @react-native-firebase/app is always required.

Open a terminal window to install this dependency.

Adding Firebase credentials to your iOS app

The Firebase provides a GoogleService-Info.plist file that contains all the API keys as well as other credentials for iOS devices to authenticate the correct Firebase project.

To get the credentials, go to the Firebase console and create a new project. After that, from the dashboard screen of your Firebase project, open Project settings from the side menu.

Then, go to the Your apps section and click on the icon iOS to select the platform.

Firebase platform selection screen

Enter the application details and click on Register app.

Firebase app registration screen

Then download the GoogleService-Info.plist file as shown below.

Firebase plist download screen

Open Xcode, then open the file /ios/rnAnonChatApp.xcodeproj file. Right-click on your project name and choose the Add Files option, then select the file to add to this project.

Contextual menu in Xcode

Now, open ios/rnAnonChatApp/AppDelegate.m and add the following header.

Within the didFinishLaunchingWithOptions method, add the following configure method:

Open a terminal window to install pods.

Adding Firebase credentials to your Android app

Firebase provides a google-services.json file that contains all the API keys as well as other credentials for Android devices to authenticate the correct Firebase project.

Go to the Your apps section and click on the icon Android to select the platform.

Firebase platform selection screen

Then download the google-services.json file as shown below.

Firebase json download page

Now add the downloaded JSON file to your React Native project at the following location: /android/app/google-services.json.

After that, open android/build.gradle and add the following:

Next, open android/app/build.gradle file and at the very bottom of it, add the following:

Adding Firebase Anonymous Auth

To support the anonymous login feature in the current app, make sure you install the following package:

Now go back to the Firebase console of the project and navigate to the Authentication section from the side menu.

Firebase console side menu

Go to the second tab Sign-in method and enable the Anonymous sign-in provider.

Sign-in method tab beneath Authentication header
Toggle to enable anonymous sign-in

That’s it! The app is now ready to allow the user to log in anonymously.

Setting up an authentication flow

To complete the navigation of the current React Native app, you have to set up the authentication flow. Create a new file src/navigation/AuthNavigator.js and make sure to import the following as well as both stack navigators created early in this tutorial.

Then, create an AuthContext that is going to expose the user data to only those screens when the user successfully logs in, that is, the screens that are part of the SignInStack navigator.

Define the AuthNavigator functional component. Inside it, create two state variables, initializing and user. The state variable initializing is going to be true by default. It helps to keep track of the changes in the user state.

When the user state changes to authentication, the initializing variable is set to false. The change of the user’s state is handled by a helper function called onAuthStateChanged.

Next, using the hook useEffect, subscribe to the auth state changes when the navigator component is mounted. On unmount, unsubscribe it.

Lastly, make sure to pass the value of user data using the AuthContext.Provider. Here is the complete snippet:

To make it work, open App.js and modify it as below:

Now, build the app for a specific mobile OS by running either of the commands mentioned:

Open up a simulator device, and you are going to be welcomed by the login screen.

Anonymous chat app welcome screen on mobile device

Adding SignIn functionality

Right now the app is in a state where you can use the Firebase authentication module to implement real-time signing in and signing out functionalities. Start with the screen/Login.js file to add sign-in functionality. Import the auth from @react-native-firebase/auth as shown below:

Then, inside the Login functional component, define a helper method that will be triggered when the user presses the sign-in button on this screen. This helper method is going to be an asynchronous function.

Lastly, add this method as the value of the prop onPress for TouchableOpacity.

Adding sign-out functionality

To add a sign out button, open navigation/SignInStack.js. This button is going to be represented by an icon on the right side of the header bar of the ChatRoom screen.

Start by importing Icon and auth statements.

Then, add a logOut helper method that will be triggered when the user presses the icon. This method is going to be inside SignInStack.

Lastly, add headerRight in the options of Stack.Screen for ChatRoom.

That’s it. Now, go back to the device in which you are running this app and try logging into the app. Then using the icon in the header bar, log out of the app. This completes the authentication flow.

Successful anonymous app login

In the Firebase console, check that the user uid is created whenever a new user signs in the app and the identifier says anonymous.

Anonymous user list in Firebase

Add another screen

To enter the name of the chat room that is going to be saved in the database (which we will setup later using Firestore), create another screen called screens/CreateChatRoom.js.

This screen component is going to use a state variable called roomName to set the name of the room and store it in the database. The UI of the screen is going to be an input field as well as a button. The helper method handleButtonPress (as described below in code snippet) is going to manage the setting of a chat room. Later, you are going to add the business logic of saving the name.

Then, go the navigation/SignInStack.js file to add this newly created screen to the stack. Start by importing the screen itself.

Next, add the Stack.Screen for CreateChatRoom in the stack as the second route in the navigator.

Lastly, to navigate to this new screen, using the navigation prop, add a headerLeft option in the screen ChatRoom as shown below. Make sure to convert the options to a function in order to use the navigation prop.

Here is the output you are going to get:

Chat room creation and navigation is enabled

Conclusion

That’s it for this part. By now you have learned how to set up a real-time authentication flow using Firebase and react-navigation and add an anonymous sign-in method.

In the next part, you are going to explore how to integrate Firestore to use a real-time database with this chat app, integrate react-native-gifted-chat to implement chat functionalities and UI, and create sub-collections in Firestore.

One thought on “Build an Anonymous Chat App with React Native and Firebase

Leave a Reply

Your email address will not be published. Required fields are marked *

Total
0
Share