anchor

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

1
Javascript team leader
2
Happy owner of the cutest cat
3
Anime lover
4
Mobile enthusiast

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.

fcm
FCM
Firebase Cloud Messaging is a free cloud service provided by Firebase (Google). It is widely used by both web and mobile developers to implement notifications into different platforms (Web, Android, iOS).

An interesting FCM feature is Topic messaging. It allows sending push messages to multiple devices that have opted-in to a particular topic.

It's quite easy here to set receiving notifications on the client-side and sending them from the server-side.

In the case of sending push messages to the topic, there is no need to store device tokens.
one signal
OneSignal
OneSignal is one more service for mobile (Android, iOS) and web push notifications, email, SMS & in-app messaging.

The most interesting features among others are:

1) sending push messages to target large groups of devices directly by data filters
2) personalizing notifications with Tags

'Tags' is something interesting to talk about. But a bit later.
tl;dr
Budget restrictions and changes
If you need 100% push message delivery in every app state then skip the silent notifications and try alert notifications (also known as notification-only in FCM).

To notify client about some event in background mode (and if long pool/websocket doesn't suit your purpose), you can try silent notifications. But! When your app ends up in a killed state such a push message doesn't pop up (at least within React Native).

Task

The task seemed easy:

  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:

1. Alert: 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.

If you can identify what's in this image, you're smarter than 98.9999% reading this

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

3. Weekly: 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)

mint
All right, send a background, intercept it by the listener, check the language and whether to display it. it's in the bag!
Great Man Quotes
Who'd have thought that it's not that simple

The key to the solution. 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.

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.

Details. 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!)

Solution. 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.

Why it didn't work. 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)

mint
Notification Only, ~6 Topics for the one Location
It isn't a quote, I just like how highlighting looks
Oh, god, what funny memes

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. :)

The key to the solution. 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)

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

${LOCATION_ID}_${LANGUAGE}_${NOTIFICATION_TYPE}.

Example: 8a7fd442-7e2b-42ff-9c83-0cd4aeced5db_EN_ALERT.

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.

Why it didn't work. 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!

A bit off topic
You may think that Solution #1 is just Ivan's fleeting hobby for cozy winter evenings. But actually, considerable time and energy have been expanded during the research.

This research explored a number of native code solutions within iOS development to handle push messages in the killed app state clearly. Notifications Service Extension was also considered. But we gotta be able to stop in time.

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

mint
To hell with this goddamn
Firebase Messaging!
Quite angry Ivan
I've got you're not up on anime - this is Goku from "Dragon Ball Z"

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.

The key to the solution. 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!)

Solution. 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.

That will be all. Till we meet again.
Build Your Team
with Freshcode
Author
No items found.

Share 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
A 30-minute discovery call is scheduled with you
We address your requirements and manage the paperwork
You receive a tailored budget and timeline estimation

Talk to our expert

Nick Fursenko

Nick Fursenko

Account Executive
With our proven expertise in web technology and project management, we deliver the solution you need.
We review your inquiry and respond within 24 hours
A 30-minute discovery call is scheduled with you
We address your requirements and manage the paperwork
You receive a tailored budget and timeline estimation
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
Looking for a Trusted Outsourcing Partner?