anchor
Insights /  
How to Implement Push Notifications [Real Case]

How to Implement Push Notifications [Real Case]

May 27, 2021
->
8 min read

This is not technical documentation! This is not a guide on how to implement push messaging!

It's just a first-hand story about how we decided to realize push notifications on the Twitter aggregator app. What challenges we were faced with. How we dealt with it. What ideas initially we had and which ones stood tests of time successfully.

We'll briefly touch upon the key concepts to understand what is a push message in the Twitter aggregators and what is the app state in React Native (and why it's quite a tricky thing).

P. S.: And as a bonus, you'll find here some memes (wildly unfunny, of course).

About me

{{list-bl43-1="/custom-block-to-blog/one-page"}}

Technologies

I am going to talk about both push notification platforms we used just briefly.

To begin with, we used React Native on the client-side. And here the story begins.

{{list-bl43-2="/custom-block-to-blog/one-page"}}

Task

<medium>The task seemed easy:<medium>

  1. to send the push message with some data to the mobile app
  2. to display (or not display) push messages in one of the available languages (English, Spanish) according to the selected language and display notifications app settings.

The application allows customizing user's location categories and subcategories (states and cities) to ensure that the targeted tweets reach the right audience. For example, in order to NY citizens receive information about heavy snowfall and traffic jam in Times Square on time.

We'll refer to these categories as 'Locations'.

Ok, let's move on.

There are 3 notification types in the app:

<medium>1. Alert:<medium>  push messages about emergencies and other events

It's a tweet that contains specific keywords, for example, Amber Alert, Silver Alert, and others. Alert messages effectively inform users during all types of regional and local emergencies.

{{img-1="/custom-block-to-blog/one-page"}}

<medium>2. Daily:<medium> once-per-day push message. More often it's a post with the highest number of likes on Twitter.

<medium>3. Weekly:<medium> once-per-week notification, chosen on the same principle as Daily notification.

Well, I think this point is clear. If not, drop your questions in the comments below the video!

Solution #1 (Spoiler: Failed)

{{quote-bl43-3="/custom-block-to-blog/one-page"}}

{{img-2="/custom-block-to-blog/one-page"}}

<medium>The key to the solution.<medium> The client subscribes to the Topic → the server sends a Silent (Background) push message to the Topic → the client receives it and processes it by Javascript code → finally, it defines to display it or not and chooses a display language.

{{img-3="/custom-block-to-blog/one-page"}}

Sounds fantastic! It's easy to implement, reliable, and trouble-free. Bit slow (due to additional processing). Juicy!

As you might have guessed, there was some kind of trick with reliability. :) But, in fairness, it worked fast and was easy to implement.

<medium>Details.<medium> There are several app states in React Native:

  1. Foreground (Active) — the app is running in the foreground mode right now
  2. Background — the app is running in the background mode but it's still alive
  3. Quit — the application was closed by the system
  4. Killed — the application was forcibly closed by the user

Moving ahead, killed state was what exactly killed our solution (goodness, what the pun!)

<medium>Solution.<medium> We are subscribing to the Location Topic (Location Id), calling the background (silent) handler, fetching notifications, checking selected app language and notification app settings (on/off), and choosing whether to display it on the user's device screen or not.

<medium>Why it didn't work. <medium> If you read the RNFirebase documentation, then the code we'd assigned to process silent notifications should be executed perfectly in the minimized (Background / Inactive) and closed (Quit) modes.

But FCM guys either forgot to mention or were tactfully merged (uh, how strongly I suspect the second one) one more mode type, namely the killed state. How do I explain this delicately... Ivan and other guys on the project, for a while, believed that quit state === killed state (hell no!). Due to the fact that we counted 2 different states as one (and the RNFirebase documentation says that this should work), we found ourselves in a quite awkward situation. Accordingly, we could understand that this solution wouldn't work in the killed state, because there is no one to execute the code. The application is just sleeping.

All right. The show is over. Lights out.

Solution #2 (Spoiler: We were too lazy to do it)

{{q-1="/custom-block-to-blog/one-page"}}

{{img-4="/custom-block-to-blog/one-page"}}

Okay, let's remember the conditions we had.

  1. Location — or rather, subscribing to Location Id.
  2. Language — upon which notification content depends.
  3. Notification type — alert, daily, weekly, we all remember. :)

<medium>The key to the solution.<medium> Maybe it's a time to set aside old ways with silent notifications that depend on the app 'awakening' and triggering push alerts.

Why shouldn't we cast off the shackles of the past and try Alert notifications (notification-only)? They are displayed independently and you don't have to do anything. Is it cool? It's really cool!

Well, but how can we do it?? How can we do it when our Locations, Languages, and Notification Types can be turned off? (ohhh sh*t)

<medium>Solution.<medium> And what if we add all these things to the name of the Topic? Then it would look something like this

{{code-bl43-5="/custom-block-to-blog/one-page"}}

In that case, we need to subscribe to all Location Topics + selected language + on/off displaying settings (Alert, Weekly, Daily). Subsequently, it causes a dozen of topics subscribings and unsubscribings when you're going to change settings.

<medium>Why it didn't work. <medium> Is it cool? No! Why isn't it cool? Because we'll need 6 Topics for 1 Location (1 Location * 2 Languages * 3 Notification Types).

It's too much, isn't it?

What if there will be more languages and notification types? What if push alerts logic will be expended or modified? Spawning more and more topics is a really bad idea. I mean, OF COURSE, I don't mind. But writing a lot of code to handle subscribings and going mad when one of them breaks down... Well, thanks, I'll pass up. I'm too lazy, and future ME just will hang himself, fixing all this chaos.

Round!

{{fact-bl43-6="/custom-block-to-blog/one-page"}}

Solution #3 (Spoiler: IT got off the ground, lol)

{{quote-bl43-8="/custom-block-to-blog/one-page"}}

{{img-5="/custom-block-to-blog/one-page"}}

The quote by someone called Ivan describes our team's feelings in the final stages of push notifications implementation perfectly.

After reinventing the wheel and thinking about unworkable solution #2, salvation finally came.

<medium>The key to the solution.<medium> During the Notifications Service Extension research, I found the OneSignal platform. Of course, I was lazy to overwrite existing push notifications for mobile and backend, BUT there was one interesting feature that captured my attention. And it was worth leaving Firebase Messaging and going to OneSignal.

Tags. That was a win.

  1. OneSignal tags are a key/value store for every data you want to put
  2. There is some tag limit depending on the account type (free or paid) but that's often enough
  3. You can group and target specific devices via OneSignal tags (wow!)

<medium>Solution. <medium> That's all. All I had to do was making some changes to the backend code and creating tags management on the mobile.

Now, when you change settings (e. g., turn on/off notifications or location/language) you will need to update the OneSignal tag for the mobile client. No need to subscribe to the new topics. It's simple: call the function and update it.

Summary

And now let's bring some seriosity. Both of described technologies are GOOD, depending on the task. It's not something you can just give preference in the context of app messaging.

Before adding a notification that is something more than just a default alert, think about its functionality. Think about how to make it workable in different app states and device states, given such contributing factors as:

  1. Localization (app settings)
  2. Custom display settings
  3. Interceptors for handling buttons, images, etc.
  4. Power saving mode (for example, silent push notifications may not work on iOS)

Consider the structure of notifications and how can you implement them. And only then choose a push notification service. Firebase Messaging, OneSignal, or something customized.

{{img-6="/custom-block-to-blog/one-page"}}

{{about-ivan-green="/material/static-element"}}

Shall we discuss
your idea?
Uploading...
fileuploaded.jpg
Upload failed. Max size for files is 10 MB.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
What happens after you fill this form?
We review your inquiry and respond within 24 hours
We hold a discovery call to discuss your needs
We map the delivery flow and manage the paperwork
You receive a tailored budget and timeline estimation