You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击通知唤醒NET MAUI Blazor应用时卡顿且仅显紫色背景

.NET MAUI Blazor FCM通知唤醒加载异常问题

问题现象

  • 已通过Plugin.Firebase NuGet包实现FCM消息收发,前台可正常接收通知
  • 应用处于后台时,点击通知唤醒应用,仅显示MAUI默认紫色背景,BlazorWebView内容无法加载
  • 移除MainPage中的BlazorWebView,仅保留Label组件时,点击通知能正常显示Label内容
  • 调试时Razor页面断点完全不触发,仅MainActivity.OnCreate方法执行,且调用base.OnCreate触发MauiProgram.RegisterFirebaseServices时崩溃
  • 已将Razor页面精简至最简形式,仍未定位到问题根源

相关代码

MainActivity.cs

using Android;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Runtime;
using AndroidX.Core.App;
using AndroidX.Core.Content;
using Microsoft.Extensions.Configuration;
using Plugin.Firebase.CloudMessaging;

namespace MauiSample;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    public static bool AppCenterConfigured { get; set; }

    protected override void OnCreate(Bundle? savedInstanceState)
    {
        try
        {
            var intent = this.Intent;

            HandleIntent(Intent);

            CreateNotificationChannelIfNeeded();

            base.OnCreate(savedInstanceState);

        }

        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    protected override void OnNewIntent(Intent? intent)
    {
        try
        {
            base.OnNewIntent(intent);
            HandleIntent(intent);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private static void HandleIntent(Intent? intent)
    {
        try
        {
            if (intent is not null)
            {
                FirebaseCloudMessagingImplementation.OnNewIntent(intent);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
    {
        try
        {
            Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
#if ANDROID23_0_OR_GREATER
#pragma warning disable CA1416 // Validate platform compatibility
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
#pragma warning restore CA1416 // Validate platform compatibility
#endif
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private void CreateNotificationChannelIfNeeded()
    {
        try
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
            {
                if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.PostNotifications) != Permission.Granted)
                {
                    ActivityCompat.RequestPermissions(this, new[] { Manifest.Permission.PostNotifications }, 0);
                }
            }

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
                CreateNotificationChannel();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private void CreateNotificationChannel()
    {
        try
        {
            var channelId = $"{PackageName}.general";
#if ANDROID26_0_OR_GREATER
            var notificationManager = GetSystemService(NotificationService) as NotificationManager;
            if (notificationManager is not null)
            {
                if ((int)Build.VERSION.SdkInt > 26)
                {
#pragma warning disable CA1416 // Validate platform compatibility
                    var channel = new NotificationChannel(channelId, "General", NotificationImportance.Default);
                    notificationManager.CreateNotificationChannel(channel);
#pragma warning restore CA1416 // Validate platform compatibility
                }
            }

            FirebaseCloudMessagingImplementation.ChannelId = channelId;
#endif
            //FirebaseCloudMessagingImplementation.SmallIconRef = Resource.Drawable.ic_push_small;
        }
        catch(Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
}

MauiProgram.cs

using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.Logging;
using WaybackMaui.Authentication;
using Radzen;
using Microsoft.Kiota.Abstractions.Authentication;
using Shared.Settings;
using Microsoft.Extensions.Configuration;
using System.Reflection;
using Microsoft.Maui.LifecycleEvents;
using Plugin.Firebase.CloudMessaging;
using Plugin.Firebase.Analytics;
using Wayback.ViewModels;
using Serilog;
using Plugin.Firebase.CloudMessaging.EventArgs;
using WaybackMaui.Services;

#if IOS
using Plugin.Firebase.Core.Platforms.iOS;
#elif ANDROID
using Plugin.Firebase.Core.Platforms.Android;
#endif

namespace WaybackMaui
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Debug()
            .WriteTo.Console()
            .WriteTo.AndroidLog()
            .CreateLogger();

            Log.Logger.Debug("proba konzole");

            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .RegisterFirebaseServices()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            builder.Logging.ClearProviders();
            builder.Logging.AddSerilog();

            builder.Services.AddAuthorizationCore();
            builder.Services.AddTransient<CustomAuthenticationStateProvider>();
            builder.Services.AddTransient<AuthenticationStateProvider>(s => s.GetRequiredService<CustomAuthenticationStateProvider>());
            builder.Services.AddTransient<DialogService>();
            builder.Services.AddTransient<IAccessTokenProvider, AccessTokenProvider>();
            builder.Services.AddTransient<JwtTokenAuthenticationProvider>();
            builder.Services.AddTransient<IJwtTokenAuthenticationProvider, JwtTokenAuthenticationProvider>();
            builder.Services.AddTransient<ICustomAuthenticationStateProvider, CustomAuthenticationStateProvider>();
            builder.Services.AddTransient<IFirebaseService, FirebaseService>();
            builder.Services.AddTransient<FirebaseService>();

            var assembly = Assembly.GetExecutingAssembly();
            var environment = GetCurrentEnvironment();
            var fileName = $"{assembly.GetName().Name}.appsettings.{environment}.json";

            using var stream = assembly.GetManifestResourceStream(fileName);

            var configBuilder = new ConfigurationBuilder()
                .AddJsonStream(stream);
            var configuration = configBuilder.Build();

            var apiSettings = configuration.GetSection("ApiSettings").Get<ApiSettings>();

            if (apiSettings == null)
            {
                throw new Exception("Api Settings not available");
            }

            builder.Services.AddSingleton(apiSettings);
            builder.Services.AddMauiBlazorWebView();            

            builder.Services.AddRadzenComponents();

#if DEBUG
            builder.Services.AddBlazorWebViewDeveloperTools();
            builder.Logging.AddDebug();
#endif

            return builder.Build();
        }

        private static string GetCurrentEnvironment()
        {
            #if DEBUG
            return "Development";
            #else
            return "Production";
            #endif
        }

        private static MauiAppBuilder RegisterFirebaseServices(this MauiAppBuilder builder)
        {
            try
            {
                builder.ConfigureLifecycleEvents(events => {
#if IOS
                    events.AddiOS(iOS => iOS.WillFinishLaunching((app, launchOptions) => {
                        CrossFirebase.Initialize();
                        FirebaseCloudMessagingImplementation.Initialize();
                        return true;
                    }));
#elif ANDROID
                    events.AddAndroid(android => android.OnCreate((activity, _) =>
                    {
                        CrossFirebase.Initialize(activity);                        
                    }));
#endif
                });

                CrossFirebaseCloudMessaging.Current.TokenChanged += FcmTokenChanged;

                return builder;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                return builder;
            }
        }

        private static void FcmTokenChanged(object? sender, FCMTokenChangedEventArgs e)
        {

        }

        private static void Current_NotificationTapped(object? sender, FCMNotificationTappedEventArgs e)
        {
            try
            {
                var notificationData = e?.Notification?.Data;
                if (notificationData != null && notificationData.ContainsKey("link"))
                {
                    //Do something with the link
                }
            }
            catch(Exception exc) { 
                Console.WriteLine(exc.ToString());
            }
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp.myapp" android:versionCode="1">
    <application android:allowBackup="true" android:supportsRtl="true" android:networkSecurityConfig="@xml/network_security_config" android:label="myapp">
        <meta-data android:name="google_analytics_default_allow_analytics_storage" android:value="true" />
        <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
        <receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.myapp.myapp" />
            </intent-filter>
        </receiver>
    </application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="34" />
    <uses-permission android:name="com.google.android.gms.permission.AD_ID" />
</manifest>

内容的提问来源于stack exchange,提问作者steakoverflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 22:52:02