4

I want to add push notifications to an chat application I am working on.

Initially I thought that I should write business logic to detect that a message wasn't delivered and then attempt to send the notification for the unread message. If a user's online presence is detected, I can skip the push notification call.

However, after doing some research, I discovered this answer from a support engineer at PubNub.

The answer states that they don't really care whether the subscription is active, they just send GCM/APNS requests for all messages.

The publisher does not know or care whether subscribers are active (foreground) or inactive (background or not running at all - kill state) on the device. Publisher always publishes the message with a GCM (and possibly APNS) payload.

Active apps will receive both and will prevent the display of the push notification via the OS's push msg receiver listener.

Inactive apps will receive only the push notification and display that. When end user taps the push msg, it will open the app where you can get the missed message and display the full content in your app's UI.

If I understand correctly, this would display a notification if the app is in the background and trigger a method (didReceiveRemoteNotification iOS, ??? Android) if the app is open. I could then choose to display a local notification depending on my own logic.

Is this good design or do chat applications generally make more effort to detect if a message was delivered before falling back to push notifications?

0

3 Answers 3

5

It depends on the notifications. Are we notifying incoming or pending messages?

For incoming messages, we have no choice; we send the notification for each new message and delegate the message handling to the client, who proceeds according to its state. On the server side, it's fire and forget.

On the client side, things are different because each platform (iOS and Android) handles push notifications in different ways. On iOS, notifications are handled by the O.S. and forwarded to the app after tapping the screen. On Android, they can be handled by the system or the app (but not both), depending on the notification format and the app's state.

In both cases, the app decides what to do with the notification1. It can show, hide2 or ignore it.

Keep in mind that sending push notifications per chat message also concerns the client side too because message handling has a cost in terms of computational resources.

As for pending messages, the solution is easier and cheaper.

Assuming you have a chat server, the server knows the state of the messages. Delivered means it was pushed to the client. Received means the client acknowledges receipt (or it fetched the room's activity recently). So, notifying pending messages is about tracking the transition from delivered to received. For instance, our chat server sets a timeout with each delivered message. If by the time the timeout expires, the message remains as delivered; the server sends the notification. Otherwise, we abort.

This way, we only send notifications in specific situations, cutting-down costs and saving resources on both the client and server.


1: Otherwise, the server side needs to know every single state of every single client. Imagine applications at the scale of WhatsApp... It could be possible with enough resources, but I think it would be absurdly expensive in many senses

2: Silent notifications

3

I have used ejabberd chat server (Used by WhatsApp) in one project. Team have implemented notification functionality in the following manner :-

For offline User case

  • If chat message can't be delivered because user is offline, we pushed that message to notification queue (RabbitMQ)
  • Notification service will pick notification from this queue and push it to device (Android/iOS).

User receive's push notification, touch it and go inside app to perform defined action.


If user is connected to chat server, chat library will receive message on handler and app itself can generate required notification in this case.

You can send push notification using Amazon SNS service or can also integrate GCM and APNS.

Design wise Notification Queue makes chat and push notification asynchronous. So it is easy to pick notification and send using Notification service. There could be other ways to do this but better not to put conditions/processing in flow of chat message. It will introduce extra delay in message delivery.

Hope this will help.

1

You can send a notification foe each but as far as I know iOS only has the ability to do a custom trigger if the app is open. So you may want to look into tracking a user a different way.

You can also track if a user is active through a couple different ways.

One way would be on foreground and background events. If a user opens the app or returns to it a call is made to let the server know the user is active and does not need to send a push. When the user backgrounds the app then there can be a call made to let your server know the user is away and should send push notifications.

Depending on how your server and app connect to each other the server can track if a user is active based on an active connection or the length of time from the last request. (The app may need to make periodic calls to the server when in the foreground which can increase your server load just to let it know that you are active.)

I know that in the past an app that I have worked on has used a foreground/background call to let the server know if a user was currently active (but it was not for a chat specific app)

2
  • 1
    Actually it is possible to send a silent push note to an iOS app even when the app is not running. You can include some metadata with the silent push to let the app construct the visible local notification. Jul 18, 2017 at 20:59
  • 1
    Do not use silent push for it. They are rate limited! The number of background notifications allowed by the system depends on current conditions, but don’t try to send more than two or three per hour. developer.apple.com/documentation/usernotifications/… Jan 23, 2020 at 2:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.