Xamarin Android发布版Firebase应用内通知失效问题求助
基于Xamarin开发的Android应用,使用FirebaseMessaging实现通知接收:
- 调试模式下,应用后台(关闭状态)、前台(运行状态)的通知功能均正常
- 切换为发布模式或安装APK包后,仅后台通知可正常接收,前台应用内通知完全失效(无法触发
OnMessageReceived及后续UI更新逻辑)
已完成的配置:生成并添加SHA-1密钥至Firebase控制台、下载并导入对应版本的google-services.json
相关代码片段
获取Token:
public string GetToken() { string token = CrossFirebasePushNotification.Current.Token; return token; }
前台通知接收服务:
[Service(Exported = false)] [IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })] public class FirebaseService : FirebaseMessagingService { public override void OnMessageReceived(RemoteMessage message) { if (message.GetNotification() != null) { long longDate = message.SentTime; DateTime start = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); DateTime dateTimeNotif = start.AddMilliseconds(longDate).ToLocalTime(); EventCatch newNotif = new EventCatch { Id_Client = AccesData.clientCourant.Id_Client, Id_Compte = AccesData.compteCourant.Id_Compte, NotifTitle = message.GetNotification().Title, NotifBody = message.GetNotification().Body, Lu = false, NotifDateHeureEnvoi = dateTimeNotif, }; AccesData accesData = new AccesData(); accesData.SauvEventLocal(newNotif); accesData.OnNewEvent(newNotif); } } }
通知事件与UI更新逻辑:
// 触发通知事件 public void OnNewEvent(EventCatch eventCatch) { RecupNotif?.Invoke(eventCatch, EventArgs.Empty); } // 页面注册委托 AccesData.RecupNotif += ShowNewNotification; // UI更新函数 private void ShowNewNotification(object sender, EventArgs e) { btnAlertNotif.BackgroundColor = Color.Red; }
1. 修复代码混淆导致的服务丢失
发布模式默认开启ProGuard/R8混淆,大概率是Firebase相关类或自定义服务被混淆,导致系统无法识别FirebaseService。
在Android项目的ProGuard.cfg(或proguard-rules.pro)中添加以下规则:
# 保留Firebase核心类不被混淆 -keep class com.google.firebase.** { *; } -keep class com.google.android.gms.** { *; } # 保留自定义的FirebaseMessagingService子类(替换为你的命名空间) -keep class 你的命名空间.FirebaseService { *; } # 保留EventCatch类及属性,避免序列化失效 -keep class 你的命名空间.EventCatch { *; }
确认项目属性的「Android Options」→「Packaging」中已正确引用混淆规则文件,R8模式下会自动继承ProGuard规则,无需额外配置。
2. 确认Firebase服务的Manifest注册
Xamarin会根据属性自动生成Manifest条目,但发布模式下可能出现注册异常,可手动添加服务声明:
<service android:name="你的命名空间.FirebaseService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
同时检查[IntentFilter]的action拼写是否完全正确,可临时将Exported = false改为Exported = true测试(后续根据安全需求调整)。
3. 验证发布版本的SHA密钥与配置文件
- 确保Firebase控制台中添加了发布签名的SHA-1和SHA-256密钥(调试与发布密钥不同,需分开配置)
- 重新下载对应发布版本的
google-services.json,替换项目文件后,将其Build Action设置为GoogleServicesJson - 核对项目属性「Android Signing」中,发布模式使用的签名文件与Firebase控制台添加的密钥完全匹配
4. 调整通知Payload格式
Firebase通知分为两种类型:
- Notification Payload:前台时会被系统直接展示,不会触发
OnMessageReceived(调试模式下可能因环境差异例外) - Data Payload:无论前后台,都会触发
OnMessageReceived
如果当前使用的是Notification Payload,建议修改为包含Data字段的格式,示例:
{ "to": "目标设备Token", "data": { "title": "测试标题", "body": "测试内容" } }
同时修改OnMessageReceived逻辑,通过message.Data["title"]、message.Data["body"]获取内容。
5. 确保UI更新在主线程执行
发布模式下线程限制更严格,修改UI更新函数,强制在主线程执行:
private void ShowNewNotification(object sender, EventArgs e) { Device.BeginInvokeOnMainThread(() => { btnAlertNotif.BackgroundColor = Color.Red; }); }
6. 排查发布版本日志
通过adb命令查看发布版本的Firebase相关日志,确认服务是否正常触发:
adb logcat -s FirebaseMessagingService FirebaseInstanceId
查看是否有OnMessageReceived的日志输出,或服务启动失败的错误信息。
内容的提问来源于stack exchange,提问作者Little_Dev

