I added a push notification to my app, and I receive the notification only the app is running. When I click on the notification, the application detects it and when I got to the point where I want to navigate to specific page, I got on error: System.InvalidOperationException: 'Window was already created'
My FireService:
using Android.App;
using Android.Content;
using AndroidX.Core.App;
using Firebase.Messaging;
[Service(Exported = true)]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class FirebaseService : FirebaseMessagingService
{
public FirebaseService()
{
}
public override void OnNewToken(string token)
{
base.OnNewToken(token);
if (Preferences.ContainsKey(StorageKeys.Public.GCM))
{
Preferences.Remove(StorageKeys.Public.GCM);
}
Preferences.Set(StorageKeys.Public.GCM, token);
}
public override void OnMessageReceived(RemoteMessage message)
{
base.OnMessageReceived(message);
var notification = message.GetNotification();
SendNotification(notification.Body, notification.Title, message.Data);
}
private void SendNotification(string messageBody, string title, IDictionary<string, string> data)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
foreach (var key in data.Keys)
{
var value = data[key];
intent.PutExtra(key, value);
}
var pendingIntent = PendingIntent.GetActivity(this, MainActivity.NotificationId, intent, PendingIntentFlags.OneShot);
var notificationBuilder = new NotificationCompat.Builder(this, MainActivity.ChannelId)
.SetContentTitle(title)
.SetSmallIcon(Resource.Drawable.ic_notification)
.SetContentText(messageBody)
.SetChannelId(MainActivity.ChannelId)
.SetContentIntent(pendingIntent)
.SetPriority(2);
var notificationManager = NotificationManagerCompat.From(this);
notificationManager.Notify(MainActivity.NotificationId, notificationBuilder.Build());
}
Android MainActivity:
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
internal static readonly string ChannelId = "MyChanel";
internal static readonly int NotificationId = 123456789;
public override void OnBackPressed() { }
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
if (Intent?.Extras != null)
{
foreach (var key in Intent?.Extras.KeySet() ?? [])
{
if (key == "NavigateTo")
{
var page = Intent?.Extras.GetString(key);
if (Preferences.ContainsKey("NavigateTo"))
{
Preferences.Remove("NavigateTo");
}
if (!string.IsNullOrEmpty(page))
{
HandleNotification(page);
}
}
}
}
else
{
CreateNotificationChanel();
}
}
private void CreateNotificationChanel()
{
if (!OperatingSystem.IsOSPlatformVersionAtLeast("android", 26))
{
return;
}
var channel = new NotificationChannel(ChannelId, "BSI Notification Chanel", NotificationImportance.Default);
var manager = (NotificationManager)GetSystemService(NotificationService);
manager.CreateNotificationChannel(channel);
}
private void HandleNotification(string navigateToPage)
{
WeakReferenceMessenger.Default.Send(new PushNotificationReceivedMessage
{
PageToNavigate = navigateToPage
});
}
}
Then the App receives the message where I try to navigate to the page that is in the push notification data.
public partial class App : Application
{
public App(SecurityService securityService, UserService userService)
{
InitializeComponent();
SubScribeOnNotificationNavigation();
MainPage = new NavigationPage(new SplashPage());
}
private void SubScribeOnNotificationNavigation()
{
WeakReferenceMessenger.Default.Register<PushNotificationReceivedMessage>(this, async (recepient, messaage) =>
{
await AppShell.Current.GoToAsync(messaage.PageToNavigate);
});
}
}
The code passes and returns to MainActivity and the throws an error. I tried some different scenarios, but all failed with the same error.
My other concern is that the message is only received while the app is running.
thnx
EDIT
I added to the manifest.xml the default notification id meta data.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" package="hu.bsi.info" android:versionName="1.0">>
<application android:usesCleartextTraffic="true"
android:allowBackup="true"
android:icon="@mipmap/appicon"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:label="BlackStageInfo">
<meta-data android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id" />
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.location.network" android:required="false"/>
<queries>
<intent>
<action android:name="android.media.action.VIDEO_CAPTURE"/>
</intent>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE"/>
</intent>
<intent>
<action android:name="android.intent.action.DIAL"/>
<data android:scheme="tel"/>
</intent>
</queries>
<uses-sdk android:targetSdkVersion="34" android:minSdkVersion="24"/>
</manifest>
I am getting an error: Severity Code Description Project File Line Suppression State Error APT2260 resource string/default_notification_channel_id (aka hu.bsi.info:string/default_notification_channel_id) not found. This error is likely caused by an issue with the AndroidManifest.xml file or an Android manifest generation attribute in a source code file.