CrossGeeks / PushNotificationPlugin

Push Notification Plugin for Xamarin iOS and Android

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Android: Cannot show notification when the App is in foreground

kpto opened this issue · comments

When the notification payload doesn't include priority or channel_id. I expect that the notification will be shown if I set the DefaultNotificationChannelImportance to high or above, but it doesn't.

After reading the source code, I suspect that the first if block in OnReceived of DefaultPushNotificationHandler is wrongly written, as shown below.

if ((parameters.TryGetValue(SilentKey, out var silent) && (silent.ToString() == "true" || silent.ToString() == "1")) || (IsInForeground() && (!(!parameters.ContainsKey(ChannelIdKey) && parameters.TryGetValue(PriorityKey, out var imp) && ($"{imp}" == "high" || $"{imp}" == "max")) || (!parameters.ContainsKey(PriorityKey) && !parameters.ContainsKey(ChannelIdKey) && PushNotificationManager.DefaultNotificationChannelImportance != NotificationImportance.High && PushNotificationManager.DefaultNotificationChannelImportance != NotificationImportance.Max))))
{
    return;
}

For easier reading, I split the condition to multiple parts.

var isSilent = parameters.TryGetValue(SilentKey, out var silent) && (silent.ToString() == "true" || silent.ToString() == "1");
var channelUndefined = !parameters.ContainsKey(ChannelIdKey);
var priorityUndefined = !parameters.ContainsKey(PriorityKey);
var priorityIsOrAboveHigh = parameters.TryGetValue(PriorityKey, out var imp) && ($"{imp}" == "high" || $"{imp}" == "max");
var defaultImportanceBelowHigh = PushNotificationManager.DefaultNotificationChannelImportance != NotificationImportance.High && PushNotificationManager.DefaultNotificationChannelImportance != NotificationImportance.Max;

if (isSilent || (IsInForeground() && (!(channelUndefined && priorityIsOrAboveHigh) || (priorityUndefined && channelUndefined && defaultImportanceBelowHigh))))
{
    return;
}

In my case, the result would be

if (false || (true && (!(true && false) || (true && true && false))))
{
    return;
}

and therefore exits the method.

I am not sure is this behaviour a mistake or intended, so I didn't create a pull request for this.

Below is how I initialize, it is run in OnCreate of my Application class.

            PushNotificationManager.DefaultNotificationChannelImportance = NotificationImportance.High;
            PushNotificationManager.Initialize(this, cats, resetToken, true, false);

The issue is that setting DefaultNotificationChannelImportance to high is not enough, the notification payload must have priority defined and set to high as well.

With notification contains only message and DefaultNotificationChannelImportance set to high:
false || (true && (!(true && false) || (true && true && false))) => true, method exits, notification is NOT made

With notification contains priority high and DefaultNotificationChannelImportance set to high:
false || (true && (!(true && true) || (true && true && false))) => false, method continues, notification is made

@kpto We had the same problem.
The Android system creates its own default channel if the channel_id is not included in the push payload.

This behaviour can be suppressed by making an entry in the AndroidManifest.

AndroidManifest.xml
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/default_notification_channel_id" />

MainApplication.cs
//Change for your default notification channel id here.
PushNotificationManager.DefaultNotificationChannelId = Resources.GetString(Resource.String.default_notification_channel_id);