Image taken from Unsplash

Creating WhatsApp Clone Using Firebase

Bilguun Batbold
Quick Code
Published in
7 min readMar 23, 2019

--

In this tutorial, we will be making use of Firebase to create a WhatsApp clone.

Prerequisites

I will not be going through the entire detail of implementing this app, mainly just the logic and code files. This tutorial assumes that you do have an existing knowledge of working with simple apps for iOS, and we will build on that. But do not fret, I will include the entire source code below for your reference if you with to learn it line by line.

For this tutorial I have used XCode 10 and Swift 4.2.

Tutorial

Let’s first create a new project, FakeChat in any folder you like. You can choose to include or exclude Core Data / Unit / UI Tests, as I will not be covering them here.

Creating New Project with Pods

Create a single view app `FakeChat`

Next we will be installing various pods that will be used in this tutorial:

pod init
open Podfile -a Xcode
Add the required pods
pod install

Now that we have installed the required dependencies, let’s create a new Firebase Project. Beginners in Swift will benefit greatly from the best Swift tutorials.

Setting Up Firebase

Head over here and press Go To Console on the top right (make sure you are logged in).

After that, click Add Project with default settings and locations. In production apps, you may want to change the location depending on your needs.

Select Project Overview and add a new iOS App to the Project, Make sure to use your iOS Bunde ID, since it has to be unique for our app to work. Replace com.bilguun.FakeChat with something unique to you such as com.yourorgname.FakeChat

Click on Register app and download the GoogleService-Info.plist. We will add this to the root of our project.

Make sure to add FakeChat as our target

Now the only thing we really need to do is to add the the following in our AppDelegate.swift file didFinishLaunchingWithOption method.

FirebaseApp.configure()let database = Database.database().reference()database.setValue("Testing")

Creating Database

Now Firebase currently offers 2 types of databases that support cloud syncing. These are Cloud Firestore and Realtime Database. Essentially Cloud Firestore is an upgraded Realtime Database.

Cloud Firestore is Firebase’s new flagship database for mobile app development. It improves on the successes of the Realtime Database with a new, more intuitive data model. Cloud Firestore also features richer, faster queries and scales better than the Realtime Database.

It is easier to scale and can model complex models and is better overall in the long run. However, to keep things simple, we will be sticking to the Realtime Database.

Realtime Database

Next, go back to Firebase Console and do the following:

This will create a Realtime Database in testing mode, which means, users do not have to be authenticated to read and write into this database. We will be changing the rules eventually but let’s go ahead with this so we can test our app.

Go ahead and run our iOS app on a simulator. Once it has started up, when u click on Database in Firebase, you should see something like below:

Our set value method worked!

Great! Once our app has finished launching, we have referenced the root of our realtime database, and set a new value Testing

We will now set aside Firebase Database, and come back to it again when we are ready to send messages. Let us now implement our ViewControllers and Signup / Login logic for our users.

Registering and Logging in

Let’s go to Authentication and click on Email / Password and enable that. What we are doing here is that we are giving the ability to our users to signup using email or password. We won’t checking the validity of the emails or authenticity of the users in this tutorial.

Firebase also has a lot more options to allow users to signup / login, feel free to explore that and incorporate that in your app.

Creating ViewControllers

This will be our initial storyboard

Let’s go about and create our initial storyboard. Here we will have just 2 screens embedded in Navigation Controller. Our welcome screen has input fields for email and password. We can then either login or register. Once we have done either one of those, we can present our Chats ViewController

See the screen recording above to get the gist of the current flow.

Handling Registration and Logging in

Update your main ViewController.swift to be like this. Make sure to connect the IBOutlets and IBActions in the storyboard to prevent crashing.

Let’s now run the app and register a new user

Enter whatever email you want and a password. Click register and the app should take you to the ChatsViewController after a brief delay.

Authentication page

In the Firebase, refresh the Authentication page and you should see a new user that we have just registered. What we have is:

  • Identifier — Email we used
  • Providers — Icon showing what type of authentication it is
  • Created — Created date
  • Signed In — Date user last signed in
  • User UUID — Unique identifier assigned to each user
  • Password column not shown since it is sensitive data. It will be hashed and stored accordingly.

Go back to the main page and try logging in. Once the user has successfully logged in, we once again show the ChatsViewController.

ChatsViewController

Looks pretty decent!

This is what we will be implementing in our ChatsViewController. The basic idea is as follows:

  1. Create a custom model that will hold message, incoming, sender
  2. Create custom table view cell to define message alignment and background colour based on the model received. If there sender is not you, show the sender name on top of the message
  3. Display the cells in the table view.
Chat Message Cell
Chats View Controller

This is all we really need to display the messages accordingly. Let’s now connect our TableView data to Firebase! We will send a message and ensure that we can get it back on another simulator. When it comes to the database, MongoDB tutorials can make complex tasks simple and working with information straightforward.

Connecting to the Firebase database

We are going to add 2 new methods to be able to communicate with Firebase Database:

  1. Send message to the firebase when send button is clicked.
  2. Add a listener to observe database changes.

I will not bore you with too many words, so here is the actual implementation

Go through the code and try to understand what exactly happened. The new methods are sendButtonDidTap and getMessages. That is all required to properly communicate with our Firebase Database. Go ahead and run the app, register 2 users if you have not done so, and login with them on a simulator or your phone. The end result should be something like this:

The messages are sent instantly, and received instantly as well.

Concluding Thoughts

About our app

Yes I know, although our WhatsApp clone kind of works, it does not have any idea / concept of friends. Which means at this stage, the ChatsViewController acts like 1 huge group where all your registered members can send and receive messages. In order to incorporate the idea of sending messages to friends / groups / rooms, our Database structure will need to be changed to facilitate that. Perhaps I will give an update on how you can achieve that using Firebase in the near future. If any one does want to know how that can be done, feel free to let me know as well.

Firebase can be a really powerful tool to get started with real time information exchange if you do not have the necessary skills or resources to get your own server. In the future I will update this or create a new tutorial that covers implementing our own service using Sockets / MongoDB instead of Firebase. But to get started, Firebase provides a super neat way of allowing real time information sharing.

The final source code can be found here.

If anyone finds these useful, feel free to share this or let me know should there be an error / bad practice / implementations.

Have fun coding!

--

--