Giter Site home page Giter Site logo

[iOS] System sound instead of custom sound for push notification plays when the app is in killed(Not lauched) state about notifee HOT 26 CLOSED

umang-simform avatar umang-simform commented on August 21, 2024 2
[iOS] System sound instead of custom sound for push notification plays when the app is in killed(Not lauched) state

from notifee.

Comments (26)

helenaford avatar helenaford commented on August 21, 2024 1

mmm, this is interesting. Do you have details of the iOS version that you saw the bug appear in? I'm wondering if this is an iOS 14 issue only thing or have you seen it happen with multiple versions?
Also, do you have some more details of how you're displaying the notification, are you using displayNotification inside a onBackgroundEvent?

There could be some overlap with invertase/react-native-notifee#192 using a notification extension.

from notifee.

helenaford avatar helenaford commented on August 21, 2024 1

@umang-simform thank you for all the info you've provided on this issue. Will close due to lack of an actionable outcome.

Regarding your last query, this is something I'm working on currently so all events can be handled by notifee

from notifee.

Krunal-K-SimformSolutions avatar Krunal-K-SimformSolutions commented on August 21, 2024

@Salakar: Any update?

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@helenaford I am on the latest stable iOS 14.3 using iPhoneX. And yes, I am using displayNotification but not sure how does onBackgroundEvent will be helpful in this scenario.
So basically this is the final function to display the notification:

const showNotifications = async ({ title, body, action, badge, sound, isForeground }, navigation) => {
  if (IS_ANDROID && title === '') {
    return;
  }
  const channelId = await getChannelId(isForeground);
  const notificationForIos = getIosNotificationJson(isForeground, action);
  const notificationForAndroid = getAndroidNotificationJson(channelId, isForeground, action);

  if (badge !== undefined && badge !== '-1' && sound !== null) {
    notificationForIos.sound = sound;
    notificationForAndroid.sound = sound;
  }

  if (badge !== undefined && badge !== '-1') {
    try {
      const isLogin = await getAsyncStorage(true);
      if (isLogin) {
        notificationForAndroid.badgeCount = parseInt(badge);
        notificationForIos.badgeCount = parseInt(badge);
      }
    } catch (error) {
      consoleLog(trackEventLogName.FirebasePushNotification.showNotifications, error);
    }
  }

  notifee.onBackgroundEvent(async ({ type, detail }) => {
    if (type === EventType.PRESS || type === EventType.ACTION_PRESS) {
      handleNotificationTap(navigation, detail.pressAction.id);
    }
  });

  notifee
    .displayNotification({
      title: title,
      body: body,
      android: notificationForAndroid,
      ios: notificationForIos
    })
    .catch((error) => consoleLog(trackEventLogName.FirebasePushNotification.showNotifications, error));
};

Let me know if you need anything from my end.

from notifee.

helenaford avatar helenaford commented on August 21, 2024

Thanks for the details, basically I'm trying to suss out at what bit of the pipeline it's failing.

Do you know if the background listener is firing, is there a possibility the notification is displayed by fcm instead, bypassing Notifee? Sorry if this is a dumb question, want to make sure I cover all possibilities. It's known the background listener when the app is quit, isn't 100%, hence the linked issue which is in progress. That'll allow you to bypass the background listener and utilise the remote message properties.

Or it could be a case, that it is being fired by Notifee and it's failing to load the sound :( which is what I think you're describing.

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

This is really difficult to check when the app is in a killed state. But I guess yes, The issue might be that when the app is terminated we might not be able to mutate the sound property from the APS, Do you have any idea what should be the ideal scenario for this case? Also as a side note when apple introduced iOS 14 then the app was crashing on receiving push notifications so to fix that issue we have to disable the method swizzling for firebase. Hope this might help

from notifee.

Eramirez06 avatar Eramirez06 commented on August 21, 2024

any update?

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

I debugged the issue, The thing is when the app is in background or killed state the notification methods are not firing up so no methods are being called in JS as well as in AppDelegate.m

from notifee.

helenaford avatar helenaford commented on August 21, 2024

hey thanks. what version are you using, there's an open issue that someone reported a few days ago about v1.0.0 but I can't replicate this locally, after multiple re-installations.

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

Currently, we are on "0.15.2" but we will be going to update soon to 1.0.0

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@helenaford On inspecting further, I found that even when we just push the app to the background mode, then also this event is not getting fired:

messaging().setBackgroundMessageHandler(async (remoteMessage) => {
   IS_IOS && onMessageReceived(remoteMessage.data, null, false);
 });

And when I looked in the appDelete.m file, I am not able to find logs there as well but notification is showing up but with default sound instead of our custom

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

@umang-simform what exact JSON are you sending to the FCM REST API? (minus device tokens - please paste it in here).

Verify you are sending content-available contents per rnfirebase.io docs and then if you are getting a notification anyway you are likely sending a notification payload, which is handled by the underlying firebase-ios-sdk with no ability to get control in the code. There is a matrix of what handlers are called in what app states based on what JSON payload you send, on rnfirebase.io I think as well as in the firebase messaging docs. It pays to memorize it, as this stuff is very subtle

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy Here is the exact JSON:

const payload = {
          to: "1234",
          notification: {
            title,
            body: `Message from ${sendersName} ${groupName ? `in ${groupName}` : ''}`,
            action: 'mainList',
            badge: 56,
            sound: 'default',
          },
          data: {
            title,
            body: `Message from ${sendersName} ${groupName ? `in ${groupName}` : ''}`,
            action: 'mainList',
            badge: 56,
            sound: 'default',
          },
          priority: 'high',
          timeToLive: 60 * 60 * 24, 
        }

Let me know if you need anything else from my end

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

The second paragraph in my comment applies, your json was as I guessed. You'll need to alter your json

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

Okk, We just checked the code and found that we removed that content-available key 5 months before not sure why. But today we will try adding it again and I will update you if it solves the issue

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy Latest update, messaging().onMessage handler for the foreground notification is getting called. But still messaging().setBackgroundMessageHandler this handler is not getting triggered even in the background as well as in killed state.
Also we have done several changes today which are:

  1. Added "content-available" : true
    So now our JSON is looking like this :
{
    "to": "Token here,
    "notification": {
        "title": "Working Good",
        "body": "add your message",
        "badge": 14,
        "sound": "default"
    },
    "data": {
        "title": "Working Good",
        "body": "add your message",
        "badge": 14,
        "sound": "default"
    },
    "priority": "high",
"content_available": true
}
  1. we re-enabled method swizzling for firebase so now our appDelegate contains only one method that is didRegisterForRemoteNotificationsWithDeviceToken rest of all are removed,
  2. Removed FirebaseAppDelegateProxyEnabled entry from info.plist file
    I am really confused how one event can work fine while the other doesn't :(

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy @helenaford I tried changing the location of methods based on the guide and I am getting two different behaviors with two different versions, on 0.15.2 I am getting foreground notification event only where notification shows up in both cases but when push received in the background plays default system sound and our background handler is not getting called.

But then I updated the package to the latest 1.1.0 and things are a bit weird,

  1. On foreground it seems working fine
  2. But things are different, for background, the is getting the notification twice, One is with the default sound and one is with the custom sound so I added logs there to check and found that the notification with the default sound is showing up directly without our background Handler and the one with custom sound is getting triggered by our background handler
  3. I tested in killed/terminated state and here I am getting a single push with the default sound

Here is code of my index.js where I placed background handler:

import App from './App';
import React from 'react';
import { name as appName } from './app.json';
import messaging from '@react-native-firebase/messaging';
import { AppRegistry, Text, TextInput } from 'react-native';
import { setBackgroundMessageHandlerSub } from './app/globalUtility';

Text.defaultProps = Text.defaultProps || {};
Text.defaultProps.allowFontScaling = false;
TextInput.defaultProps = TextInput.defaultProps || {};
TextInput.defaultProps.allowFontScaling = false;

messaging().setBackgroundMessageHandler(async (remoteMessage) => {
  console.log('On background event');
  setBackgroundMessageHandlerSub(remoteMessage);
});

const HeadlessCheck = ({ isHeadless }) => {
  if (isHeadless) {
    // App has been launched in the background by iOS, ignore
    return null;
  }

  return <App />;
};

AppRegistry.registerComponent(appName, () => HeadlessCheck);

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

My comment about having a notification block meaning that the underlying sdk handles it without getting control in your code is the important bit I think. Data only FCM is not reliable but will give you control if it's delivered. Notification blocks in FCM are reliable but you don't get control. Limitations of the system unless I am missing something

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy But the thing is it should be working nice, No?
It should be as easy as just adding both handlers one for the background and one for the foreground having displayNotification function inside them.
Currently, I am not able to figure out why we are not able to have consistent behavior, Even having double notification while the app is in the background sound really off here, and based on the thing that when the app is in the killed state I think it is not able to make it to the JS code that is the notifee part.
Even if you guys can provide us any solution that might include doing it all on the native side will also helpful as we honestly don't want to do anything else than having proper UI and custom sound.

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

I find letting go of 'should' thoughts helpful when handling ios fcm

What did you learn when you read the matrix of FCM payloads, handlers called, and app states on ios from firebase docs? How does that intersect with your planned usage of specific payloads and custom sounds?

I feel as though we are debating what you want but you haven't read the docs to see what is possible yet.

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy @helenaford Yep, I read it carefully now (multiple times actually :D) and I am thinking of few things,

  1. We are still using legacy APIs to send FCM so that might be the first thing we should change to Admin SDK as I just learned yesterday that legacy API of firebase (https://fcm.googleapis.com/fcm/send) does not support APNS and other key's so passing them in JSON might have no impact at all
  2. I also found that we will need to ditch the Notification payload completely in order to get rid of the duplicate push notifications as mentioned in the docs it will be utilized by the iOS library
  3. So when I tweaked the JSON again a bit (still using the legacy API to test notification as it can be done by postman easily let me know if you have a better solution to test various JSONs) so when we removed the notification key we are not getting a notification when the app is in killed/not launched state. But it comes immediately on the foreground and on the background it comes after 5-6 seconds but with the custom sound
  4. So I read the docs once again and there I found that I must pass the apns headers in JSON for the data only messages so I tried to add them in the JSON through the legacy API like below but it still didn't work
{
    "to": "Token",
    "data": {
        "title": "Working Good",
        "body": "add your message",
        "badge": 16,
        "sound": "default"
    },
    "apns": {
      "payload": {
        "aps": {
          "content-available": true
        }
      },
      "headers": {
        "apns-push-type": "alert",
        "apns-priority": 10,
        "apns-topic": " Bundle ID of the app"
      }
    },
    "priority": "high",
	"content-available": true
}

So I looked into the firebase docs and I was not able to find any mention of apns values with the legacy API docs but it was there in the notification section and they mostly provide snippet with the admin SDK. so today we will be trying admin SDK with the above-mentioned JSON,
Please let me know if you think of any possible solution that can fix the notification not showing up in the killed state.

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

There is not unfortunately a solution for data only FCM receipt in killed state, and in fact in background (stopped but not force quit) it is unreliable. By definition content available data only cloud messages are for caching content but the apple docs indicate the app must behave even if the cloud message is not delivered

This is a platform limitation.

It works enough to be interesting, and to handle many use cases, but for reliable delivery you must use a notification payload, with its own set of limitations

This is a very painful part of ios development

I do think you understand it all now though, that's a huge step. I use firebase cloud functions to send FCM with payloads I want, running in the local firebase emulator for development, and little shell scripts to http get them from the local emulator. Translate well to deployment of the function when it works

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

okk cool, So at some point if we might need to look forward if we are not able to get React-Native and native-IOS SDK play along nicely,
I could understand that, Only thing that still keeps me bugging is if we go with the only native portion then do you think we will be able to do this thing without much hassling, I think we might need to create a Notification service thing, let us try more today with different payloads if it works as expected then it will provide us relief.

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

@mikehardy @helenaford I guess you can close this ticket as there is no way to receive a notification with data only payload while in a killed state. But I found that if we remove the react-native-firebase/messaging and install the Firebase messaging SDK directly through pod then the notification is coming just fine in a killed state so there is definitely something that is breaking inside the RN-Firebase.
Also now We are able to mutate the notification as we want (we just need to modify the sound key though) by using the UN Notification service extension.

from notifee.

mikehardy avatar mikehardy commented on August 21, 2024

Very interesting, I was not aware the underlying sdk had ability there that react-native-firebase did not have. They should be 1 to 1, that bears investigation

from notifee.

umang-simform avatar umang-simform commented on August 21, 2024

Yeah, To be more specific, I tried adding the package again (RNfirebase/messaging) if I can get it to work along with the notification service extension just to make things easy for us as otherwise, we will need to create methods for data communication between native and JS to exchange various data like the fcmToken which we need to pass in API to update the DB, and guess what, The notification service extension didn't get called when the app is in the foreground, so I had to add the onMessage handler back just to make sure that the notification works when the app is in the foreground.
So I have one query @mikehardy, Is it possible to disable the notification handling done by the RN-firebase/messaging part?

from notifee.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.