Chapter 11: Realtime Chat Messenger – Firebase and SwiftUI

What you’ll learn in this chapter:

  • How to work with realtime databases such as Firebase in SwiftUI
  • How to implement a Notification Center and listen to system notifications
  • Storing small pieces of data using UserDefaults

What we’ll create 🚀

In this chapter, we’ll learn how to communicate to a server with SwiftUI by building our own chat messenger app. We’ll use the Firebase realtime-database for storing and retrieving our messages. We are going to create one massive chat channel where every user can participate. Every message in our chat app shows the sender’s username. If the user itself sends the message, it gets displayed on the right side. If it’s from another user, it gets displayed on the left side. When the user opens the app for the first time, we present a login screen where he can choose his username. 

Here’s how our app will look like:

The starter project 

We prepared a starter project for you. 

Let’s take a quick tour through the project to see what’s already set up.

When we open the starter project, we see two SwiftUI views inside in the “Views” group: the ChatView, where we will prepare our chat interface, and a LoginView where the user can choose his username when launching the app for the first time. 

Let’s take a look at the LoginView. You see that it consists of a VStack containing some Text views, a TextField where the user can enter his username, and a Button to log in. The Button calls the signIn function, which grabs the usernameInput and sets it as the UserDefault using the “username“ key. UserDefaults are used for storing and retrieving small pieces of data. You can store data by assigning them to an individual key, which you can call again later for retrieving the stored data (you’ll see how to do this in a moment).

For navigation purposes, the LoginView and the ChatView are held by the MotherView using the ViewRouter as an Environment Object, just as you learned in Chapter 8.

Let’s take a look at the ChatMessengerApp struct. We use the MotherView as the entrance view and initialize the ViewRouter as a @StateObject.

Depending on whether the user has already chosen a username (we know this by checking if there’s a value assigned to the UserDefaults username key) we either initialize the LoginView or ChatView. So when the user launches the app for the first time, the LoginView will be shown. When it gets opened again, we directly navigate the user to the ChatView, since we already know his username.

Let’s try this out by running the app. Choose a username and tap on login. We navigate to our (still empty) ChatView. Now stop and relaunch the app. You see that we are directly navigated to the ChatView

Hint: If you want to choose another username after launching the app the first time, delete and reinstall it in the simulator or device the app runs on.

That’s everything already set up for us. Now we can start coding our chat messenger app!

Our message data model 🛠

For every message that we send or receive, we have to know the following: 

  • What’s the content of the message? 
  • What’s the sender’s username? 
  • Is the message sent by the user himself? 

For keeping track of this information about each message, we’re going to create a fitting data model. So, let’s create a new Swift file and name it “ChatMessage.swift”. Let’s implement a struct with the corresponding attributes. We also create a messageID property to identify each message. We simply assign a UUID instance to it every time we initialize a ChatMessage, which guarantees us that each message object has a unique identifier.

struct ChatMessage: Hashable {
    let messageText: String
    let username: String
    let isMe: Bool
    let messageID = UUID()

Great! That’s all we need for our chat message’s data model!

Let’s create some sample messages we can use for preparing our interface. Declare an array containing some messages below your ChatMessage struct:

let sampleConversation = [
    ChatMessage(messageText: "Hello how are you?", username: "Me", isMe: true),
    ChatMessage(messageText: "I'm fine and you?", username: "Another user", isMe: false),
    ChatMessage(messageText: "I'm fine as well. Thanks for asking. What are you doing right now?", username: "Me", isMe: true)

Now we are ready to prepare our ChatView!

3 replies on “Chapter 11: Realtime Chat Messenger – Firebase and SwiftUI”

Leave a Reply

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