TobiasBuchholz / Plugin.Firebase

Wrapper around the native Android and iOS Firebase Xamarin SDKs
MIT License
220 stars 49 forks source link

Prevent Notification from being shown in NotificationReceived #236

Open Raffro opened 11 months ago

Raffro commented 11 months ago

I have a app with instant messaging function. I want the user to not receive the notifications if a user is active in the chatpage.

Is it possible to use the CrossFirebaseCloudMessaging.Current.NotificationReceived event in order to stop the Notification? I tried accessing the EventHandler and then called return, but the notification is shown anyway.

andyzukunft commented 11 months ago

Hey Raffro,

I am just trying the same. And I re-read the docs. I believe you have to update the FCM message to data: "is_silent_in_foreground": true to automatically prevent the message to be displayed if the app is in foreground.

If you want to do anything else you can use the CrossFirebaseCloudMessaging.Current.NotificationReceived event. That's my assumption as of now.

[Edit] It seems the example from Tobias (https://github.com/TobiasBuchholz/Plugin.Firebase/blob/development/docs/cloud_messaging.md) uses the Legacy Http Api. Which is depracted and will be removed in June 2024. My toolkit CorePush uses the new Http v1 Api.

I get an error adding is_silent_in_foreground to the data element. It might be a possibility that is_silent_in_foreground is no longer supported with the new Api. I will have to check the new api in more detail.

andyzukunft commented 11 months ago

The issue with data is only allowed to contain string values. As such is_silent_in_foreground: "true" would be the correct format (or: our C# class needs to be a string and not a boolean).

The Google Api does also not matter (I guess) as is_silent_in_foreground is a custom field only applicable for Plugin.Firebase.

@Gekidoku I have a short question. Do you have a solution to "notify" the user (ringtone, vibration, depending on the smartphone configuration) if a silent notification is received?

Gekidoku commented 11 months ago

I don't right now. Think the correct name for the parameter in my case is background_notification

I use it when I want to send some data or retrieve data from a device without waking the device

Raffro commented 11 months ago

Yeah this is not exactly what I have meant.. The notification is definitely sent, but how to cancel it directly from the app? Is silent in background cant be modified in the received event, because the event args are read only.

If there is no such functionality at the moment i need to decide individuakky on the server whether to send a notification to a specific device or not.

andyzukunft commented 11 months ago

I think there might be a miscommunication. If you send your message with the data content is_silent_in_foreground: "true" the notification will not be displayed by the toolkit if the app is in foreground.

Btw: thanks Gekidoku for clarifying.

Raffro commented 11 months ago

So, ist it possibke to catch the notification app-side and decide to display it or not, or not?

andyzukunft commented 11 months ago

Yes. The event handler CrossFirebaseCloudMessaging.Current.NotificationReceived is triggered in both cases (is_silent_in_foreground = true, is_silent_in_foreground = false) and if is_silent_in_foreground = true you need to handle it manually if you need/want to.

With Plugin.Firebase.CloudMessaging v2.0.4 Local Notification have been implemented. I believe this is what you could use to create / handle if a silent notification is incoming in NotificationReceived and you want to show it manually.

wyyqyl commented 11 months ago

Does CrossFirebaseCloudMessaging.Current.NotificationReceived triggered when the app is closed by the user? It's not called when the app is closed.

private void NotificationReceived(object sender, FCMNotificationReceivedEventArgs args)
{
    if (args == null || args.Notification == null) return;
    _bugReportService.Report($"{args.Notification.Title}: {args.Notification.Body}");
}
CrossFirebaseCloudMessaging.Current.NotificationReceived += NotificationReceived;

I wrote my own class which extends FirebaseMessagingService, the OnMessageReceived callback will be called even the app is closed.

  [Service(Exported = false)]
  [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
  public class PushNotificationService : FirebaseMessagingService
  {
      public override void OnMessageReceived(RemoteMessage message)
      {
          Log.Info("test", "OnMessageReceived");
          base.OnMessageReceived(message);
      }

  }