Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push notifications v2 will never work reliably for iOS #1268

Closed
mfbx9da4 opened this issue Apr 7, 2022 · 9 comments
Closed

Push notifications v2 will never work reliably for iOS #1268

mfbx9da4 opened this issue Apr 7, 2022 · 9 comments
Assignees

Comments

@mfbx9da4
Copy link

mfbx9da4 commented Apr 7, 2022

After much digging I've come to the conclusion that the current proposal for push notifications v2 will never work reliably for iOS.

setBackgroundMessageHandler is super unreliable for iOS. It is only called when the payload is data-only. Data-only remote notifications are considered very low priority by apple and the device will only accept two or three per hour. They are subject to multiple extra throttling heuristics e.g. low battery mode, device is overheating.

Also with v2 there is no way to get the unread badge count easily.

Therefore I would urge you to reconsider the new v2 approach.

Have you tested v2 on iOS in production??

gz#21584

@mfbx9da4 mfbx9da4 changed the title Push notifications v2 will never work for iOS Push notifications v2 will never work reliably for iOS Apr 7, 2022
@dmitriiivashko
Copy link

dmitriiivashko commented Apr 11, 2022

Having the same issue here. Since the notifications are not data-only, setBackgroundMessageHandler is never triggered. And even if it was, Apple's throttling of silent data-only notifications makes it unusable.

So far my only option to solve this is to implement a native iOS push notification extension to customize the content and manage badge values.

@santhoshvai
Copy link
Member

santhoshvai commented Apr 12, 2022

Hey, @dmitriiivashko @mfbx9da4. Many thanks for sharing your concern here. We would need to update our documentation regarding the ios/android platform limitations and the docs will be updated soon.

I did set up a sample app to test it and got setBackgroundMessageHandler to work on a mixed payload (data + notification) when I enabled "background fetch" and "background processing" capabilities to the app. Additionally the payload must also have "content_available": true. I should note that there is some throttling there. Suppose I increment the badge count by one on the background handler. The increment doesn't always happen on every push but is rather queued. Meaning that in the next push or the push after, the badge count increments by 2 or 3 respectively.

It would be very helpful for us if you can test this at your end and get back to us regarding this.

Our current push v2 template does not have "content_available": true enabled, so we would have to add this. We are currently finalizing template customization and the docs should be available soon about this too.

@mfbx9da4
Copy link
Author

mfbx9da4 commented Apr 12, 2022

I tried with "content_available" directly using the firebase admin sdk, it never worked for me on iOS device. It is however known to work fine on Android. From my reading, setBackgroundMessageHandler is extremely flakey.

As linked previously, the primary maintainer of react-native-firebase states that mixed FCM payload will never trigger setBackgroundMessageHandler on iOS. From my perspective, I think the react-native-firebase docs are a bit misleading.

@santhoshvai
Copy link
Member

@mfbx9da4 I did read the comment but I want to reinstate that for mixed payload, it did work for me. Having enabled the background capabilities and the content_available. The background_app_refresh has to also be on for the app.

It can be flakey if on a power saver setting. But since you say that it never worked, I am curious to know if your payload is like this,

{
    "to": "<device_token>",
    "notification": {
        "body": "Test body",
        "title": "Test title"
    },
    "data": {
        // any custom fields
    },
    "content_available": true
}

I also set up the app headless entry point based on this on the FAQs on RN firebase library. Did you set it up like that too?

@mfbx9da4
Copy link
Author

mfbx9da4 commented Apr 12, 2022

Yes I did also setup the headless stuff. I also had enabled those capabilities.

From memory it was more like the following but I don't have the testing code available anymore. I was conforming to whatever types my version of the sdk had at the time and was using this method

{
    "to": "<device_token>",
    "notification": {
        "body": "Test body",
        "title": "Test title"
    },
    "data": {
        // any custom fields
    },
   apns: {
    aps: {
      contentAvailable: true 
    }
  }
}

Were you running iOS 15?

@santhoshvai
Copy link
Member

santhoshvai commented Apr 12, 2022

Hi @mfbx9da4, yes I am using iOS 15.

if apns payload is present, it will override the notification, and the structure misses "payload".

can you try the one below for your apns, this should work

"apns":{
   "payload":{
      "aps":{
         "alert":{
            "body":"Test body",
            "title":"Test title"
         },
         "custom-data":{
            // any custom fields
         },
         "content-available":true
      }
   }
}

The structure is here

@dmitriiivashko
Copy link

The problem is that getstream seems to send an aps payload with both content-available and alert

If both are specified, setBackgroundMessageHandler is never triggered on iOS and the content from alert is displayed by iOS. Yes, you can implement an iOS notification extension, but I'd prefer to deal with it with what rnfirebase has to offer.

Examples

This will wake up the app and will trigger setBackgroundMessageHandler as expected:

  const firebaseMessage: admin.messaging.TokenMessage = {
    token: pushToken,
    data: {
      my_custom_parameter: 'wow2',
    },
    apns: {
      headers: {
        'apns-push-type': 'background',
        'apns-priority': '5',
        'apns-topic': 'com.myapp',
      },
      payload: {
        aps: {
          contentAvailable: true,
          priority: 'high',
        },
      }
    },
  };
  return admin.messaging().send(firebaseMessage);

however this will display a hello world notification and will not trigger the setBackgroundMessageHandler:

  const firebaseMessage: admin.messaging.TokenMessage = {
    token: pushToken,
    data: {
      my_custom_parameter: 'wow2',
    },
    apns: {
      headers: {
        'apns-push-type': 'background',
        'apns-priority': '5',
        'apns-topic': 'com.teamgo.godisco',
      },
      payload: {
        aps: {
          alert: {
            body: 'Hello',
            title: 'World',
            subtitle: 'test',
          },
          contentAvailable: true,
          priority: 'high',
        },
      }
    },
  };
  return admin.messaging().send(firebaseMessage);

@santhoshvai
Copy link
Member

santhoshvai commented Apr 12, 2022

Hey, @dmitriiivashko I did try out the exact payload that you sent and setBackgroundMessageHandler did work.

However, as per the apple docs, alert should not be used along with content-available: 1. So this is really unreliable I think.

The background notification flag. To perform a silent background update, specify the value 1 and don't include the alert, badge, or sound keys in your payload. See Pushing Background Updates to Your App.

So I think the best way forward is to implement a native iOS push notification extension for now. Stream's backend team is actively working on supporting the firebase template customization feature. It should be available very soon. This would enable adding notifee_options payload.

I will soon be updating the docs with the platform limitations and many thanks for your inputs here.

@santhoshvai
Copy link
Member

We have updated the documentation at https://getstream.io/chat/docs/sdk/reactnative/guides/push-notifications-v2/. The current documentation clarifies the differences in payload between iOS and Android.

Furthermore, the documentation in the JS SDK at https://getstream.io/chat/docs/javascript/push_template/?language=javascript has been updated to mention the support of template customization in push V2. We would highly recommend using the template customization feature in the Stream JS SDK to customize your notifications.

I am closing this issue as I believe that the documentation updates clarify the platform limitations and the default payload. Please feel free to reopen this issue or file a new one if you would need any more clarifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants