thomasgalliker / Plugin.FirebasePushNotifications

Receive and handle firebase push notifications in .NET MAUI apps
MIT License
65 stars 5 forks source link

[Enhancement] Receiving push notification while Android app is in foreground mode #57

Closed eyeveye closed 2 months ago

eyeveye commented 3 months ago

Summary

When receiving push notification while the App is opening, it will not have an notification in the system bar. Currently need to manually create an extra popup to show the notification when the App is at foreground.

Intended Use Case

When app is at foreground, and push notification received it should show in the system bar. Would be good to have the notification show in the system bar.

sgreifeneder commented 3 months ago

+1, I was also searching for this!

thomasgalliker commented 3 months ago

This is already available (for Android). I‘m not sure if such a thing also works on iOS? Does anyone know?

sgreifeneder commented 3 months ago

Only if we override the NotificationBuilder for Android and change the logic for ShouldHandleNotificationReceived. Maybe a flag would be nice to handle this.

sovdchains commented 2 months ago

This currently is possible by setting priority to high in push notification data

sgreifeneder commented 2 months ago

Only works on iOS

sovdchains commented 2 months ago

Oh you're right, I haven't been aware of this.

thomasgalliker commented 2 months ago

Strange. Can you show me the notification message which you send? As @sovdchains said, you can set the priority flag to high which SHOULD create a local notification message - even when the app is in foreground mode. If this is not the case, it's clearly a bug.

Does such a notification message work?

{
    "message": {
        "token": "{{fcm_token}}",
        "notification": {
            "title": "Notification title",
            "body": "Notification body"
        },
        "data": {
            "priority": "high"
        }
    }
}

(Btw. you can find a decent collection of postman http calls with several different notification messages here).

sovdchains commented 2 months ago

@thomasgalliker after @sgreifeneder told me it does not work on Android I tried to recreate the issue and have been successful with being unsuccessful to show the notification on Android while the app is in foreground. The priority flag really seems to only work on iOS. I also can't find any corresponding code for Android like on iOS

thomasgalliker commented 2 months ago

Ok. Did you test with the message I posted above? I'm curious what message you used.

The code that should care about priority=high on Android can be found here. So, the bug must be in this area too.

sgreifeneder commented 2 months ago

But 2 lines above it explicitly checks for if (isInForeground == false), or?

thomasgalliker commented 2 months ago

That's wrong. I'll fix it.

sovdchains commented 2 months ago

Ok. Did you test with the message I posted above? I'm curious what message you used.

The code that should care about priority=high on Android can be found here. So, the bug must be in this area too.

I did not test your exact payload, but I checked that the data is set to the same value. I'll wait for your mentioned fix and see if this helps out. If not I'll try your raw payload.

sgreifeneder commented 2 months ago

Any update here?

thomasgalliker commented 2 months ago

Thanks for the reminder. I removed the IsInForeground check in NotificationBuilder but that does not yet seem to solve the problem.

Ok, I got it. We need to have a notification channel with importance=high. Otherwise it doesn't work. (How many times did I hit this trap already...)

thomasgalliker commented 2 months ago

Just to summarize how I managed to send a high-priority notification which is also displayed if the Android app runs in foreground mode:

  1. You need to create a notification channel which has Importance=High (or above). If your notification channel has lower priority you still receive the notification message, but it will appear in the notification tray - and not as a foreground notification. On top of that, a warning is logged.

    new NotificationChannelRequest
    {
    ChannelId = "default_channel_id",
    ChannelName = "Default Channel",
    Description = "The default notification channel",
    LockscreenVisibility = NotificationVisibility.Public,
    Importance = NotificationImportance.High,
    IsDefault = true,
    };

    If you have no notification channels (not even the default notification channel) you cannot use NotificationBuilder. An error is logged that informs you about this situation.

  2. Run the app in foreground mode. Make sure the notification permission is granted.

  3. Send an FCM notification message with data-flag "priority: high":

    {
    "message": {
        "token": "{{fcm_token}}",
        "notification": {
            "title": "Notification title",
            "body": "Notification body"
        },
        "data": {
            "priority": "high"
        }
    }
    }
thomasgalliker commented 2 months ago

@sgreifeneder if you could quickly check my changes here and let me know if that makes sense, I'd highly appreciate it.

I have tested the changes on a Google Pixel 5 with Android 14 and it worked.

This nuget pre-release contains the fixes: https://www.nuget.org/packages/Plugin.FirebasePushNotifications/2.3.15-pre

thomasgalliker commented 2 months ago

@eyeveye @sgreifeneder @sgreifeneder thank you for raising this issue and for the patience with me. I hope you understand that this is by far not the only construction site I'm working on.

If any of you could try the latest 2.4.x pre-release and let me know if the problem was solved, I'd appreciate it. If you find more suspicious code please do not hesitate to create a new issue.

sovdchains commented 2 months ago

@thomasgalliker Thank you for providing us with those awesome libraries of yours and maintaining them so well! I will try this on monday!

sovdchains commented 2 months ago

@thomasgalliker I just validated that the issue is gone on a Samsung Tab3 running Android 8.1. Thanks again for the fix!

sgreifeneder commented 2 months ago

@thomasgalliker I can also confirm it's working, tested on Pixel 7 emulator with API level 34 and Samsung Galaxy A52 with Android 14. Used nuget version 2.4.22.

Didn't have time to check your code change yet, sry.

vchelaru commented 1 month ago

Does the fix in the latest 2.4.x pre-release also require the creation of a new NotificationChannelRequest? If so, where does the creation of NotificationChannelRequest go? I'm new to push notifications so it's not clear if this goes in my maui app or if this is done on the backend where the push notification request is sent to firebase.

Update 1

I have found the samples which assign a NotificationChannel and I've modified my code so that my MauiProgram has the following:

                .UseFirebasePushNotifications(options =>
                {
#if ANDROID
                    options.Android.NotificationChannels = new NotificationChannelRequest[]
                    {
                        new NotificationChannelRequest
                        {
                            IsDefault=true,
                            ChannelId = "default",
                            ChannelName = "Default",
                            Description = "The default channel",
                            Importance = NotificationImportance.Max
                        }
                    };
#endif
                })

I have also updated my app so it is using version 2.5.13 - presumably that's newer than the mentioned 2.4.x pre-release so it should have the fix?

If my Android app is in the background, the notifications are shown by the Android OS.

If my Android app is in the foreground, no notifications are shown; however, I do get the FirebasePushNotification.NotificationReceived event raised in my code, but no OS notification.

Is there something else I have to do to "subscribe" to a channel or perform some other kind of initialization.

Note that I tried with NotificationImportance.High and Max, neither worked.

Update 2

After further looking at the samples it seems like the push notification JSON must include the channel name, so we're now sending:

{
    "message": 
    {
        "token": "{{fcm_token}}",
        "notification":
        {
            "title": "Notification title",
            "body": "Notification body"
        },
        "data":
        {            
            "channel_id": "default"
        }
    }
}

Still no luck...