Updated: Jan 24, 2021
Push notifications are a great way to communicate with users and increase engagement. So much so that they became a must have feature for any successful app. At the end of the day one of our goals is to have engaged users that actually open and use our app. Push notifications is a great tool to achieve that.
Implementing push notifications can be very challenging for two reasons:
No guidelines - There’s actually no guidelines out there on how opening a push notification should affect the application layout and the product. What should happen when a user taps on the notification? Should I present the screen as a modal or push it to the current stack?
Hard to test manually - In order to simulate a real push notification received from both providers (FCM for android and APNS for iOS) we need to have the correct certificate, device token and know the structure of the push notification.
In this blog post I will explain how we, at Wix Engineering, address those issues in order to make Push Notifications great and easy to implement (or at least easier).
No guidelines? Let’s define them ourselves!
Before diving into the code itself, I would like to suggest one important guideline that will help us create a better product.
A push notification, in essence, is a shortcut to a screen within your application that a user is already familiar with. Opening push notifications should be intuitive and anticipated. Which means it should never create new flows in your application.
Imagine you receive a chat message notification from any of your direct messaging apps, you then open that notification and see your conversation - working well so far, right? You go ahead and reply to your friend. You then decide you want to chat with another friend, and so you press “back” expecting to see the conversations list. Instead, you see the screen that was opened before you tapped on that notification, which can be any screen of your app!
Sounds bad, I know. I see more and more applications that handle opening push notifications by presenting the related screen as a modal even though that screen actually lives in a stack and maybe also in bottomTabs. It increases the cognitive load on the user as he or she is required to reorient, since there’s no product relationship between current and previous destinations. This results in bad UX and you can read more about it here.
Our goal is to create user friendly, anticipated experience so a user would always know the state of the application layout, always aware of where the back button leads to, with zero surprises.
In this tutorial I will explain how we can achieve this goal and have a strict and expected layout hierarchy. We will use Wix’s react-native-navigation and react-native-notifications libraries and will test everything using the Detox library for e2e tests.
We will create a simple bottomTabs application with two tabs, one will be called Main and the second one will be called Chat.
This post is intended for users who are already familiar with our react-native-navigation library. I plan on adding another example for react-navigation users.
Let’s take a look at our application entry point
In the snippet above, we’re creating an application layout with a notification that triggered the initial application launch. We also register a listener for notifications opened from the background state with Notifications.registerNotificationOpened().
The layout manager will be responsible for how the layout looks at any certain point. Let’s look at layoutManager.loadRoot()
As you can see, when we have a notification, the currentTabIndex will change to the chat tab and we will pass that notification to _createChatLayout(), which will be responsible for creating the chat stack of screens (Conversations list screen --> Conversation screen).
At this point we don’t need to process the notification itself because we are supporting only one type of event.
Let’s also take a look at _createChatLayout()
Here we are checking whether the notification in question exists and then we’re adding the conversation screen to the stack. The final result will be the conversation screen presented in a stack where the back button leads to the conversations list.
And least but not last, loadChatNotification() will handle pressing the notification when the app is in background.
We create Chat tab screens children with _createChatChildren(), same as we created the layout in the initial app launch for consistency, and replace the Chat tab root with those new screens. Then we make this tab visible by changing the currentTabIndex to the Chat tab index.
And we’re good to go! Opening a push notification with userName and userId will create our layout with the conversation screen and will set the currently presented tab to the second tab which is the Chat tab.
Want to hear and learn more about React Native and React Native at Wix? Listen to the interview with Lev Vidrak and Omri Bruchim on our Wix Engineering Podcast:
Testing push notifications isn’t an easy mission. Integrating with both providers (Firebase and APNs) can be tricky. We want our tests to be fast and automatic. And to achieve that we will rely on Detox - an end-to-end testing and automation library for mobile apps which works amazingly with React Native.
Let’s add our first tests!
The first test will verify that tapping a notification when the app isn’t launched yet will open the conversation screen.
The second test will launch the app, send it to background, and then launch it again via “tapping” on a notification (imitating a user pressing it when the app is in background), and then finally will verify that the conversation screen is visible.
Implementing push notifications can be easy and straightforward. All we have to do is remember that a push notification is a shortcut to a flow that already exists in our application and each screen opened from push notifications should be presented in its natural place and have the exact same flow as in a situation where a user entered that screen normally and not through the push notification.
Applying those guidelines will provide a better experience for your users as the flows will be consistent and anticipated. Opening push notifications will always take people to a flow they are already familiar with, with zero surprises.
This blog post only mentions relevant code, you can take a look at the full code here https://github.com/yogevbd/PushNotificationsTutorial
This post was written by Yogev Ben David
You can follow him on Twitter
For more engineering updates and insights: