How to receive remote notifications after iPhone comes back online? - ios

I am currently building a laravel provider service to send push notifications to IOS devices. I have followed this tutorial for creating a sample app which is able to receive notifications.
On my server side, I used this package to handle push notifications.
During testing, the app manages to receive push notifications when the device is connected to wifi/4G, during foreground/background/inactive modes. However if I send the push notification to the app when its offline, on connecting the device back to the internet I do not receive any notifications.
According to the apple documentation, the APNS service stores any notification which is sent when the device is offline and delivers it to the client after connection is re-established. It is supposed to dispose of any notifications if the device stays offline for a long time (duration not exactly specified). However I am keeping the device offline for only a minute before going online. Can anyone please suggest a solution?

Thanks to Brandon I managed to know what the problem actually was. The next challenge I faced was how to integrate the expiry period for the notification in the message payload using the davibennum/laravel-push-notification package. Since there was no documentation regarding this, I had to go through the source code to find out how to define the expiry period. Turns out the expiry time can be set simply by defining it like this in the message payload:
'expire' => Carbon::now()->addDays(30)
Basically you are passing a date time instance, which will then be transformed to the apns-expiration header of the request.

Related

If APNs only stores the last push notification per device while offline, why am I receiving all? Working with Firebase

I have a production iOS app that is receiving, in most cases, all the missed push notifications while the device was offline once I connect it again to the Internet. This app uses Firebase Messaging to receive notifications and the default/recommended configuration code in Firebase's docs.
According to Apple, I would only expect only the last notification to arrive:
Quality of Service, Store-and-Forward, and Coalesced Notifications
Apple Push Notification service includes a Quality of Service (QoS)
component that performs a store-and-forward function. If APNs attempts
to deliver a notification and the destination device is offline, APNs
stores the notification for a limited period of time and delivers it
when the device becomes available again. This component stores only
the most recent notification per device and per app. If a device is
offline, sending a notification request targeting that device causes
the previous request to be discarded. If a device remains offline for
a long time, all its stored notifications in APNs are discarded.
source: apple push notifications documentation
Is Firebase doing something to ensure notifications delivery? I couldn't find any clear doc about this in the case of iOS.
On the other hand, I am working on a completely new version that uses the same Firebase Instance and client configuration, but this time I only receive the last notification no matter what. This new version is not yet released, so I'm testing it in a debug configuration (the production one is release config).
Not sure what is happening here; it's pretty confusing since the implementations are near identical. Has APNS/Firebase any policy regarding the release config and the QoS? I couldn't find anything related to that...
Thank you in advance!

How to know Push Notification delivery status

I am using push notification in an app. Everything is going fine.
Sometimes message sent from server but in app side it does not receive.
In this situation I have to know which message is missing to deliver(app did not receive).
Is there any way to know from server side which message is received by app and which are not?
Nopes, push notifications are fire-and-forget.
Apple will not tell you the following:
Will not tell whether the message was sent successfully or not
Will not tell if the user has opted out of Push Notifications
Many other things but anyways...
However
On the other hand, when the user has opted for Push Notifications then your app can handle this but to a certain extent:
Basically, you could add logic in the -didReceiveRemoteNotification: and -didFinishLaunchingWithOptions: to contact your server and tell your server that the message was received.
If it wasn't received within a particular time slot then you can resend it.
But as you see, this could lead to a possible scenario of flooding an innocent user with the same push notifications.
In a sense, harassing him to tap your stupid push notification, which in turn may lead him to switch off push notifications for your app entirely but mostly he would delete the app and maybe even give it a low rating?
Serves you right, I'll say.
Anyways, if you go ahead with this, you would need to implement an identification pattern where you insert a unique message identifier into the payload of the push notification and when your app gets this push notification, it should send this message identifier back to the server.
Your server should then log that a particular device token returned a message identifier, which means it received that particular push notification.
Your server can check on a hourly/daily/whateverly basis and resend a particular message to those device tokens that have not reported back with the relative message identifier.
Again, this means your server might need to work OT sometimes.
There are other issues with this whole approach:
User received push notification but dismisses it rather than opening your app with it
Your server will assume the user did not see the push notification and will send this push notification again
Ghost device tokens
User accepted push notifications at first but later revoked this privilege
User uninstalled the app
Basically, device tokens that once use to receive push notification but no longer do, most probably due to your message flooding reputation
User received push notification but taps it at a later time
might get same push notification multiple times (very irritating)
User received push notification but taps it when there is no internet connectivity
User received push notification but your server is down, possibly fried \m/
You can circumvent the last 3 scenarios by having even more logic in your app that queues the message id's that are to be sent to the server and removes it only when the server responds successfully.
So you see, too much work, server-side + client-side.
Plus it's a massive performance degrader on the server-side when dealing with a good volume of users as well as lowering the performance of your app by a wee bit.
The Feedback Service
The Apple Push Notification Service includes a feedback service to
give you information about failed push notifications. When a push
notification cannot be delivered because the intended app does not
exist on the device, the feedback service adds that device’s token to
its list. Push notifications that expire before being delivered are
not considered a failed delivery and don’t impact the feedback
service. By using this information to stop sending push notifications
that will fail to be delivered, you reduce unnecessary message
overhead and improve overall system performance.
Query the feedback service daily to get the list of device tokens. Use
the timestamp to verify that the device tokens haven’t been
reregistered since the feedback entry was generated. For each device
that has not been reregistered, stop sending notifications. APNs
monitors providers for their diligence in checking the feedback
service and refraining from sending push notifications to nonexistent
applications on devices.
1. If you are asking about notifications not delivered on a device which has application installed on the device and just because of notification getting expired before it is delivered or something else, notifications are not delivererd.
Then the answer is
Nope.
It does not provide support where in you can check if the Notifications is expired and not delivered on a valid device:
any option to know if apple app get the push notification?
Refer to Moshe's answer in above link. I am including his answer here so that it is useful to everyone in future even in case the link becomes dead.
The short answer, you can't, since APNS is one way. However, since an
app can execute arbitrary code upon receipt of a notification, you can
use this to say, send an http request to your own server when the
notification is recieved.
2. If you asking of the notifications not delivered as user has uninstalled the application then you can refer to meda's answer in this post.
Hope this helps you and let me know if you have any queries regarding my explanation.
You can get the the delivery report of Push notification, Not from server but from your app, using "Service Extension" and modifying little bit in your Push json. Checkout this link for detailed explanation.

How do iOS Push Notifications work?

How do iOS "push" notifications get delivered to a particular device without that device needing to poll a server?
For example, let's say I have received a new message on Facebook. Facebook notifies Apple that my device should receive a notification as such. But how does Apple know which device/IP to push the message to?
Each device can be updated with data using their own unique device tokens. This picture explains everything . .
It was too much for me to put in a comment so.
From the documentation.
Apple Push Notification service (APNs) propagates push notifications to devices having applications registered to receive those notifications. Each device establishes an accredited and encrypted IP connection with the service and receives notifications over this persistent connection. Providers connect with APNs through a persistent and secure channel while monitoring incoming data intended for their client applications. When new data for an application arrives, the provider prepares and sends a notification through the channel to APNs, which pushes the notification to the target device..
I suggest reading the documentation for more information and how to use and configure. It's all there.
Push Notifications
I created an infographic to explain the workflow of push notifications. Hope this is helpful.
Device does not keep polling the server for the push notifications.
To keep it simple, consider an iPhone is connected to internet. On connecting to internet iPhone establishes connection to Apple Push Notifications server this connection is open connection which means data can be thrown to iPhone from server the moment data arrives to server.
Apple does not use HTTP protocol for Push notifications but if you understand HTTP Protocol its almost a similar methodology.
http://en.wikipedia.org/wiki/Push_technology#HTTP_server_push
There is a really nice exaplanation of push notifications in this article.
In iOS, apps can’t do a lot in the background. Apps are only allowed to do limited set of activities so battery life is conserved.
But what if something interesting happens and you wish to let the user know about this, even if they’re not currently using your app?

If I use Apple Push Notification service for instant messaging will apple block my account?

I want to create an iOS chatting app using APNS. If I have 10,000 active and they are continuing chatting, will apple block my developer account ? Is there any limitation regarding this?
I would discourage you from using APNS as a backbone of an "chatting app".
If you need fast chatting functionality you should write your own TCP-socket based server.
If every-few-second syncing is o.k. you can get away with a HTTP-based server backend (but all the pull-syncing can be hard on network traffic - so TCP-socket is still better choice).
You could however use APNS for fallback - when your app on certain device is not responding (i.e. is not connected to server) you can send an initial message trough APNS (to wake up your app & to notify the user there is a message waiting for him).
As soon as the user opens your app you should switch back to your TCP-socket or HTTP request based server communication.
As for your question: no, Apple would most probably (one can never know for sure) not reject your app just because of using APNS for chatting. But note (as the others said allready): messages between two users will get "lost" if they would interact too frequently - see the link Roman Barzyczak gave you.
"If you are sending multiple notifications to the same device or computer within a short period of time, the push service will send only the last one."
more information: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html
but Apple wont block your developer account :)
You can use them for messaging but you are going to quickly find out that there is no guarantee they will arrive. This is known as the black hole of push notifications. ;-)
I like this answer here.
First try to use an APNS only solution.
Make your push notifications stateless (they only serve as "Hey you have some new stuff in the server").
So when the client gets a push notification it asks the server for new data (messages or other stuff).
Use OneSignal to simplify the code that sends push notifications (from the back-end). If a user in your app gets a message after 10 seconds he dose not care if you used TCP,socket.io or xmpp...
Even Whatsapp's messages can take couple of seconds to arrive.
A chat app is not a realtime game. A delay of couple of seconds will be acceptable by end users.

APNS (Apple Push Notification Service) reliability

Our app uses APNS to receive Push Notifications. However, our client claims that some of their devices were not receiving notifications and argues to they 'must' make sure the notifications to be delivered 100%. But I have read somewhere that APNS is not 100% reliable and there should be cases which the notifications are not delivered.
I'm currently panic at how we could make sure APNS to received anytime. I have read that a case which may APNS not delivered (device may offline). But our test showing that even the device is online (Wifi or 3G), sometimes APNS were not delivered.
Is there any specific case which may APNS will not delivered? Or is there anything we (developers) can do with codes to make sure to receive all notifications? What I have done in the code is just registering the app to remote notification and write didRegisterForRemoteNotificationsWithDeviceToken, then throw the device token to our server.
Any help would be appreciated, for our client almost kill us if ALL of their devices not receiving APNS!
APNS is based on Apple Servers, and Apple doesn't give any guarantee on successful message delivery.
If the app is open (i.e. the user is using the app) while the notification arrives, iOS doesn't show a notification message, you need to handle it.
Notification shows up only when the app is backgrounded or killed.
Also implement feedback service on your server side; will help you get rid of old unwanted tokens (users who deleted the app or disabled notifications through settings).
Don't send too many notifications to a device within a short span of time, because APNS caches only 1 message/device (if the device is offline). So it can deliver the message when the device comes online. Am not sure how long the message is cached though.
Or just implement Pusher... http://pusher.com
We're facing the same problem. As everybody said, APNS is a best effort service so you can't be sure every notification will be delivered, but what you can do is to be sure of which ones have been received. This is what we're about to do. We register in our backend each notification que ship and the mobile app reports back each notification it receives. Then we set a maximum time of waiting for a notification to be received, if we don't receive the report back we try again.
I hope it might be helpful to someone (even 2 years later)
It says it quite clearly in the Apple Docs that it is not 100% gauranteed and nor should it be used as so. Its sent with "best effort".
As per Apple's guidelines, APNS is not 100% reliable service which means your app may not get push notifications from Apple servers due to some of the following reasons:
Device is offline
Your app is in the foreground state, you need to manage the push notification.
Note: Apple rejects apps which make compulsion to use notification services. (I have faced it in one of my App)
For more information, you can look into this answer
https://stackoverflow.com/a/25830955/3278326

Resources