Flutter FCM android 发布模式问题

问题描述 投票:0回答:1

我完全被这个问题难住了。我一直在测试我正在开发的应用程序的最终版本,并遇到了一个我不知道如何解决的问题。

我正在使用 FCM 通过主题向我的用户发送通知。通知通过云功能触发,作为数据消息发送,并通过本地通知包显示。在 IOS 上,它可以完美地工作,在 Android 上,它可以在调试模式下工作,然后发布模式则非常不稳定。

我已经输入了 SHA 1 和 256 密钥(发布密钥而不是调试密钥),这导致在通过 flutter run --release 推送时通知起作用(发布在 build.gradle 中正确设置以使用发布模式应用程序签名)。但是,当使用 flutter build --release 构建并作为 apk 安装时,fcm 通知根本不会通过(从应用程序推送的其他本地计划通知确实有效,因此这不是权限问题)。

奇怪的是,今天我从 FCM 控制台向所有 Android 设备推送了一条测试消息,它与昨晚应该发出的通知一起发送了。几乎就像它在队列中待处理一样,推送测试消息将待处理的消息推送到队列中。

我真的不知道该怎么办,我尝试禁用收缩并设置 r8 规则。由于调试器受到攻击,它可以在任何模式下工作,因此很难调试。

这是我的部分配置,以防我在这里犯了错误。

Pubspec.yaml

flutter_local_notifications: ^16.1.0
firebase_analytics: ^10.5.0
firebase_auth: ^4.12.0
firebase_core: ^2.16.0
firebase_crashlytics: ^3.3.7
firebase_messaging: ^14.6.8
firebase_performance: ^0.9.2+7
firebase_ui_auth: ^1.4.1
firebase_ui_firestore: ^1.5.1

构建.gradle

signingConfigs {
    release {
        keyAlias keystoreProperties['keyAlias']
        keyPassword keystoreProperties['keyPassword']
        storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
        storePassword keystoreProperties['storePassword']
    }
}

buildTypes {
    release {
        signingConfig signingConfigs.release
        minifyEnabled false
        shrinkResources false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.USE_EXACT_ALARM" />
android flutter firebase notifications firebase-cloud-messaging
1个回答
0
投票

文档表示“在 iOS、macOS、Web 和 Android 13(或更高版本)上,在您的设备上接收 FCM 有效负载之前,您必须首先征求用户的许可。”

您可以使用此代码询问用户

FirebaseMessaging messaging = FirebaseMessaging.instance;

NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);

print('User granted permission: ${settings.authorizationStatus}');

那么你应该隔离你的背景消息。

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();

print("Handling a background message: ${message.messageId}");
}

void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
 }

@pragma(“vm:入口点”) 标记一个函数(或其他实体,如类)以向编译器指示它将从本机代码中使用。如果没有这个注释,dart 编译器可能会删除未使用的函数、内联它们、收缩名称等,并且本机代码将无法调用它。

关于后台消息处理程序,需要记住以下几点:

  1. 它不能是匿名函数。
  2. 它必须是顶级函数(例如,不是需要初始化的类方法)。
  3. 当使用 Flutter 版本 3.3.0 或更高版本时,消息处理程序必须在函数声明正上方使用 @pragma('vm:entry-point') 进行注释(否则它可能会在发布模式的 tree shake 过程中被删除)。

您可以从文档

获取更多详细信息
© www.soinside.com 2019 - 2024. All rights reserved.