paint-brush
How To Build a WhatsApp Clone in React Native: Beginner’s Guide [Part 2]by@decodebuzzing
4,627 reads
4,627 reads

How To Build a WhatsApp Clone in React Native: Beginner’s Guide [Part 2]

by HarshVardhan JainNovember 26th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

A Non-Comparable WhatsApp Clone made using react-native (Expo) and Firebase (React-Native) The code in Github is till this of this project only. I will upload the entire project code after Part-3. The code for this project is till the end of the first part of the project. We need to add a ‘Switch Navigator’ to our application to the Auth screen. We will also need to Add redux and add firebase to our app.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - How To Build a WhatsApp Clone in React Native: Beginner’s Guide [Part 2]
HarshVardhan Jain HackerNoon profile picture

A Non-Comparable WhatsApp Clone made using react-native (Expo) and Firebase


In the previous part (Part 1), we installed all the packages that we needed and also checked the firebase structure in case you don't have any doubt. Now, let’s start with the real work and start 👨‍💻👨‍💻

First, let’s just see the application's file structure, and then we can start with the navigation and rest all with the help of videos.


File Structure

This will be the final file structure of our application and you might have some doubts with some files and but these will become clearer once we start building. The NavContainer.js file in the navigation and the StartUpScreen.js in the Screens folder, especially will be used later to implement the Auto-Login/Logout features. The rest of the files are clear, I suppose, but these will become soon if any doubt. If any doubt related to code, Check the Github Link


Note: Check The Github Link for this project. The code in Github is till this of this project only. I will upload the entire project code after Part-3.


Adding Fonts

First, before getting any further let’s add fonts to our application. Then we can move ahead by adding navigation to our application. If you have any doubt, please have a look at Part1(Module Installation) of this project where I explained all these things in detail


Download Fonts

https://drive.google.com/drive/folders/1wADl1_QIpVzQ72JNKkrdVm0yJUpLjCtW

Video


Adding Navigation

With that, we are ready to add navigation to our application. So, create a header and Toptabnaviagator just as in WhatsApp.


Video


If you have any doubts about AppLoading or HeaderButtons you can check my Youtube-Clone-React-Native-Part1 where I explained all these things in detail.


Working on Authentication

Now, let’s move on to the Authentication Work and for that, we will also need to Add redux. So, now let’s add both + we also need to add firebase. So, this is going to be long. Let’s get Started


Moving To the Auth Screen (Switch Navigator)

Before, getting started let’s just add a Switch navigator to our application. What is a SwitchNavigator ?


SwitchNavigator is mostly used when adding the Authentication functionality to our application. Basically, it resets routes to their default state depriving us of the back functionality. And that’s what we want. If the user is not sighed In we want the user to navigate to the Auth screen without giving the user the facility to go back to the main screen.


So, let’s modify our WhatsAppNavigator.js screen a little bit and below is the code for the whole file:

import React from "react";
import { Platform } from "react-native";
import { createStackNavigator } from "react-navigation-stack";
import { createMaterialTopTabNavigator } from "react-navigation-tabs";
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import { Ionicons } from "@expo/vector-icons";
import { MaterialIcons } from "@expo/vector-icons";

import HeaderButton from "../components/HeaderButton"; // Our HeaderButton Component
import Chat from "../screens/WhatsApp/Chat";  //-------------------- |
import Message from "../screens/WhatsApp/Message"; //                |
import Status from "../screens/WhatsApp/Status"; //                  |
import Calls from "../screens/WhatsApp/Calls"; //                    |
import Camera from "../screens/WhatsApp/Camera"; //                  Our all Screens
import Auth from "../screens/User/Auth"; //                          |
import AddDetails from "../screens/User/AddDetails"; //              |
import StartUpScreen from "../screens/StartUpScreen"; //             |
import Colors from "../constants/Colors"; //                         |
import Profile from "../screens/User/ProfileScreen"; // -------------|

const WhatsAppTopTabNav = createMaterialTopTabNavigator( // Our TopNavigator
  {
    Camera: {
      screen: Camera,
      navigationOptions: {
        tabBarVisible: false, // TabBar Shouldn't be visible here
        tabBarLabel: (TabBarInfo) => { // Adding Image as a Camera Label....You can also use 'TabBarIcon'
          return (
            <Ionicons
              name={Platform.OS === "android" ? "md-camera" : "ios-camera"}
              size={25}
              color="black"
            />
          );
        },
      },
    },
    Chats: Chat,
    Status: Status,
    Calls: Calls,
  },
  {
    initialRouteName: "Chats", // Initial tab should be the Chats Tab
    tabBarOptions: {
      labelStyle: {
        fontSize: 12,
        fontFamily: "open-sans-bold",
      },
      indicatorStyle: {
        backgroundColor: "white",
      },
      activeTintColor: "white",
      inactiveTintColor: "#D3D3D3",
      pressColor: "white",
      style: {
        backgroundColor: Colors.accent,
      },
    },
  }
);

const WhatsAppNavigator = createStackNavigator({
  MainNav: {
    screen: WhatsAppTopTabNav,
    navigationOptions: {
      headerTitle: "WhatsApp",
      headerRight: () => (
        <HeaderButtons HeaderButtonComponent={HeaderButton}>
          <Item
            IconComponent={Ionicons}
            title="Cart"
            iconName={Platform.OS === "android" ? "md-search" : "ios-search"}
          ></Item>
          <Item
            IconComponent={MaterialIcons}
            title="Cart"
            iconName="more-vert"
          ></Item>
        </HeaderButtons>
      ),
      headerTitleStyle: {
        color: "white",
      },
      headerStyle: {
        backgroundColor: Colors.accent,
        elevation: 0,
        shadowOpacity: 0,
      },
    },
  },
  Messages: Message,
  Profile: Profile,
});

const AuthNav = createStackNavigator({ //         |
  Auth: Auth, //                                  |
  AddDetails: AddDetails, //                      | 
}); //                                            |
//                                                |
const MainNavigator = createSwitchNavigator({ //  |
  StartUpScreen: StartUpScreen,//                 *What We Changed*
  Auth: AuthNav, //                               |
  WhatsAppMain: WhatsAppNavigator, //             |
}); //                                            |
//                                                |
export default createAppContainer(MainNavigator)//|


Creating And Initialising Firebase project

First, quickly go to Firebase Console and click on Add Project / Create A project. Give a Project name → Accept the Conditions → Disable/Enable Google Analytics → Create Project


Adding RealTime DataBase

I will be using the RealTime database for this app but it's your choice to use fireStore database or RealTime database.

Open the above page on https://console.firebase.google.com/u/0/project/{ProjectName}/database and click on Create Database. Specify the database location and start it in Test mode for now.


With that our firebase should look like this with default Test rules which we will change later:

Adding Firebase Storage Now simply click on the storage tab and the sidebar and click on Get started.


Now, press ‘Next’ → ‘Done’. We also need to change our security rules because the default rules allow requests only when the user is authenticated but in our case user will use storage when he/she is signing up. ⁂ He/she is !Authenticated. So, change the rules as follows:

Storage Rules

Adding Authentication Now, similarly, click on the Authentication tab in the sidebar and click on Get started, and in the “Sign-in methods” select Email/Password


Select Email/Password

Click enable and I won't be enabling the “Email link” toggle but it’s completely your choice. Of course code for that would be different then.

Adding Redux

Again, If you have any doubt about Redux, Redux Thunk, etc have a look at Part1(Module Installation) of this project.

Video


Implementing The Entire Authentication Logic

Let’s move on to the main Authentication logic where we will take a look at Redux action creators, Redux Thunk, Firebase, and of course also test our designing skills. To keep the videos short I will be pasting the content of my authentication , Input component screen as well as the AddDetails screen which are quite long. Rest we will create on our own in the video. Below are the 3 files which I will paste n the video.


Link for the Auth.js file(Sorry for not uploading the file in the drive to not make the article long by code)

https://drive.google.com/file/d/1gIy8m0uu81COi-FUzNZnVK4iDtPqPFuv/view?usp=sharing


We used the useReducer hook in above file(Which is not at all related to redux and is provided by react). The useReducer function just as a redux-reducer accepts a reducer function, and an initial state and returns the current state. UseReducer is used in a form where we have multiple inputs or when the next state depends on the previous one. You could have also used useState and have each separate state but this method is more optimized because unlike is useState you don't have to use useCallback for every state.


Link for the AddDetails.js file(Sorry for uploading the file in the drive to not make the article long by code.)

https://drive.google.com/file/d/15yJaQMfyUXyrxjExN0qWDiAAl-h9PyN2/view?usp=sharing


Also link, for the Input component:

https://drive.google.com/file/d/1p_C60YgtDTKY1gLRAoGwBF0XqbXcqUmb/view?usp=sharing


Now, let’s complete our Authentication work with this video:

Video


Finally, Authentication is nearly finished. Oof! Now we can Login/Signup but we also want “Auto-”. So, let’s work on that first then we can start working on our Home/Chat screen where we can start showing a list of users that are stored in the firebase database.


Implementing Auto-Login

Soo, Let’s also add an Auto-Login facility in our app so that the user doesn’t have to log in again and again. Basically, we need to store our token somewhere on the device and if it’s there when the App re-launches then we can navigate users to the Chat screen. But we can’t store it in redux

as redux is in memory and the data will be lost when the app re-launches. So, we will be using AsyncStorage instead which allows us to persist data offline. Also, the token that we get from firebase has a expiresIn field that tells us when the token will expire, and generally, it will expire after 1 hour. So, we have to add some logic to detect if the token has expired or not and navigate accordingly.


Video


Implementing Auto-Logout

We might be chatting in our app and after 1 hour our token will get expired in the middle of our chatting. Then as soon as we do some work related to firebase, we will get errors because our token will be expired right? For that, we need to add some logic that automatically clears our Auth redux store as soon as our token gets expired(with the help of timers). But we also need to navigate back to Auth screen and for that, we need a place that is always rendered. Yes, that is the App.js file. But there we can’t access our redux store as only our navigator is inside our provider. So, we need to wrap our Navigator inside a component where we can check if our Auth redux store is empty or not. And if it’s empty we can navigate to the Authenticate Screen. That was a mouthful. Let’s see 👀 it in 👨‍💻👨‍💻


Video


Creating Our Chat/Home Screen + Adding Logout

So, This gonna be something interesting cuz now we will be able to see some output in our app i.e See all the users Signed Up. First, in the video, let’s start up by making our UserItem component which we will pass in the FlatList


Video


If you are going by the video, I made some errors which I corrected later in the video. So, make sure you watch the entire video till the very end.


But nevertheless, we have completed the following in just 1 article

  • Navigation

  • Authentication

  • Login/Logout

  • Auto-Login/Auto-Logout

  • Showing all the Users stored in our firebase database


Wow !! we are just a step away from our complete app! So, now only the messaging part is left which I will take up in the next Part because the article is getting too long now.


Till then Stay Safe; Stay Healthy

Thank you!


This article was first published here.

Watch the Youtube introduction here: https://www.youtube.com/watch?v=eAFEvKIJsNI.