背景:使用flutter实现苹果和安卓两个平台的应用,需要国外收发消息,我们首先了唂歌FMC。
按照官方的文档,引入了两个flutter三方包。
firebase_core: ^3.0.0
firebase_messaging: ^15.0.0
在唂歌平台创建好应用后,下载安卓和苹果对应的google-services文件,放在对应的位置。
苹果需要的在开发者网站创建证书,然后上传到唂歌平台,按文档配置好Xcode的工程,因为苹果的消息推送在国内正常使用,但安卓是不行的,很快苹果的就调试成功。
但安卓的一直调不通,经过多次在国外手机测试,最终成功收到消息,我简单列一下要点。
1.settings.gradle文件在anroid目录,它的路径为anroid/settings.gradle。
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.2.1" apply false
// Add the dependency for the Google services Gradle plugin
id "com.google.gms.google-services" version "4.4.2" apply false
}
id "com.google.gms.google-services" version "4.4.2" apply false 这一行是新增的。
2.build.gradle文件在anroid/app目录,它的路径为anroid/app/build.gradle
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
// Add the dependency for the Google services Gradle plugin
id "com.google.gms.google-services"
}
id "com.google.gms.google-services" 这一行是新增的
dependencies {
// Import the Firebase BoM
implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
// Import Firebase Messaging
implementation("com.google.firebase:firebase-messaging")
}
上面这两个依赖都是新增的!!
3.AndroidManifest.xml文件在android/app/src/main目录,它的路径为android/app/src/main/AndroidManifest.xml
<!--允许全部网络访问-->
<uses-permission android:name="android.permission.INTERNET" />
<!--获取网络信息状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--获取当前WiFi接入的状态以及WLAN热点的信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 允许程序发送通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
flutter 里main文件中关键代码:
try {
await Firebase.initializeApp(options: FirebaseService.currentOptions()).timeout(const Duration(seconds: 10));
await FirebaseService().initNotifications().timeout(const Duration(seconds: 10));
} catch (err) {
logger.e('Firebase 初始化超时或失败: $err');
if (HttpRequest.isDev) {
Future.delayed(const Duration(seconds: 5), () {
CustomToast.showToast(Local.tips.tr, "0 init firebase error:${err.toString()}", seconds: 10);
});
}
}
class FirebaseService {
static FirebaseOptions currentOptions() {
if (HttpRequest.isDev) {
if (Platform.isAndroid) {
return const FirebaseOptions(
apiKey: 'appkey-android-dev',
appId: 'app-id-android-dev',
messagingSenderId: '111111',
projectId: 'project-id-android-dev',
storageBucket: "storage-bucket-android-dev",
);
}
return const FirebaseOptions(
apiKey: 'appkey-ios-dev',
appId: 'app-id-ios-dev',
messagingSenderId: '111111',
projectId: 'project-id-ios-dev',
storageBucket: "storage-bucket-ios-dev",
);
}
if (Platform.isAndroid) {
return const FirebaseOptions(
apiKey: 'appkey-android-pro',
appId: 'app-id-android-pro',
messagingSenderId: '111111',
projectId: 'project-id-android-pro',
storageBucket: "storage-bucket-android-pro",
);
}
return const FirebaseOptions(
apiKey: 'appkey-ios-pro',
appId: 'app-id-ios-pro',
messagingSenderId: '111111',
projectId: 'project-id-ios-pro',
storageBucket: "storage-bucket-ios-pro",
);
}
Future<void> initNotifications() async {
await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
// 当用户点击通知栏时触发
FirebaseMessaging.onMessageOpenedApp.listen(onMessageOpenedApp);
// 监听应用内收到的消息
FirebaseMessaging.onMessage.listen(onMessageOpenedApp);
}
Future<void> onMessageOpenedApp(RemoteMessage message) async {
try {
// 当用户点击通知栏时触发
var title = message.notification?.title ?? "message title is null";
logger.d("Notification clicked: $title");
if (HttpRequest.isDev) {
CustomToast.showToast(Local.tips.tr, "0 receive message :$title", seconds: 3);
}
} catch (err) {
logger.e('onMessageOpenedApp error: $err');
CustomToast.showToast(Local.tips.tr, "0 receive message error :${err.toString()}", seconds: 3);
}
}
}
以下是后话,不重要!!!:
我们之前没有收到消息时缺少配置
implementation("com.google.firebase:firebase-messaging")
然后还在AndroidManifest中额外添加了下面配置,这个配置会导致收到消息应用崩溃,这个是原生收到消息自定义类处理时需要添加的。我使用的是flutter,并不需要。
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
Firebase.initializeApp初始化时,在网上找到可以删除这个options参数,结果初始化失败,没有添加try catch,结果安卓一启动就卡住了!!