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

Flutter Android FCM推送Debug正常Release失效,求解决方案

Flutter Release模式下Firebase Messaging推送失效问题排查与解决

问题描述

使用Flutter SDK 3.3.5,Firebase依赖版本:firebase_core:2.1.1、firebase_crashlytics:3.0.4、firebase_messaging:14.0.3。Debug模式下Firebase Messaging功能正常,可获取Token且控制台推送成功,已配置Google Play的SHA-1/SHA-256并更新google-services.json,但Release模式下推送失效,运行时报错:

W/FlutterJNI(20984): FlutterJNI.init called more than once
E/flutter (20984): [ERROR:flutter/runtime/dart_isolate.cc(668)] Could not resolve main entrypoint function.
E/flutter (20984): [ERROR:flutter/runtime/dart_isolate.cc(168)] Could not run the run main Dart entrypoint.
E/flutter (20984): [ERROR:flutter/runtime/runtime_controller.cc(396)] Could not create root isolate.
E/flutter (20984): [ERROR:flutter/shell/common/shell.cc(606)] Could not launch engine with configuration.
E/flutter (20984): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: [firebase_messaging/unknown] java.io.IOException: FIS_AUTH_ERROR
E/flutter (20984): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:653)
E/flutter (20984): #1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:315)
E/flutter (20984): 
E/flutter (20984): #2      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:518)
E/flutter (20984): 
E/flutter (20984): #3      MethodChannelFirebaseMessaging.getToken (package:firebase_messaging_platform_interface/src/method_channel/method_channel_messaging.dart:224)
E/flutter (20984): 
E/flutter (20984): #4      FireBaseMessagingService.init (package:hr_max/Helpers/firebase_messaging_services.dart:44)
E/flutter (20984): 
E/flutter (20984): #5      GetInstance.putAsync (package:get/get_instance/src/get_instance.dart:62)
E/flutter (20984): 
E/flutter (20984): #6      MyApp.build. (package:hr_max/main.dart:158)

已尝试重新下载google-services.json,问题未解决。相关配置文件如下:

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.initiummesolutions.hr_max">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <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_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
   <application
        android:label="HR Max"
        android:icon="@mipmap/launcher_icon">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize"
            android:exported="true">
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

MainActivity.java

package com.initiummesolutions.hr_max;

import io.flutter.embedding.android.FlutterActivity;

public class MainActivity extends FlutterActivity {
}

app/build.gradle

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    compileSdkVersion 33

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.initiummesolutions.hr_max"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
    buildToolsVersion "30.0.2"

    signingConfigs {
       release {
           keyAlias keystoreProperties['keyAlias']
           keyPassword keystoreProperties['keyPassword']
           storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
           storePassword keystoreProperties['storePassword']
       }
   }
   buildTypes {
       release {
           signingConfig signingConfigs.release
       }
   }
}
dependencies {
    implementation 'androidx.work:work-runtime-ktx:2.7.0'
    implementation platform('com.google.firebase:firebase-bom:31.0.3')
}
flutter {
    source '../..'
}

解决方案

从报错信息和配置来看,问题集中在Release模式下的代码混淆、签名配置以及Firebase认证三个方面,按以下步骤排查修复:

1. 修复代码混淆问题

Release模式下开启混淆会导致Flutter入口函数或Firebase相关方法被混淆,无法正常初始化。在android/app/proguard-rules.pro中添加以下规则:

# Flutter相关规则
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }
-dontwarn io.flutter.embedding.**

# Firebase相关规则
-keep class com.google.firebase.** { *; }
-keep class com.google.android.gms.** { *; }
-keep class com.google.firebase.messaging.** { *; }
-dontwarn com.google.firebase.**
-dontwarn com.google.android.gms.**

同时在app/build.gradle的release构建类型中确保混淆开启并指定规则文件:

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

2. 确认签名证书的SHA值正确性

  • 检查用于Release签名的key.jks的SHA-1和SHA-256值,执行命令:
    keytool -list -v -keystore /path/to/your/key.jks
    
  • 确保Firebase控制台中添加的SHA值与上述命令输出完全一致,包括大小写,且对应正确的应用包名。

3. 确保google-services.json配置正确

  • 重新下载Firebase控制台的google-services.json,确认文件中的package_name与app/build.gradle的applicationId完全一致。
  • 将文件放在android/app/目录下,清理项目后重新构建:
    flutter clean
    flutter build apk --release
    

4. 调整Firebase初始化时机

报错中显示在GetInstance.putAsync中初始化Firebase Messaging,可能因初始化时机过早导致问题。修改初始化逻辑,确保先初始化firebase_core再初始化firebase_messaging:

// 在main函数中先初始化firebase_core
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

// 在FireBaseMessagingService.init中延迟获取Token
Future<void> init() async {
  // 确保firebase_core已初始化完成
  await Future.delayed(const Duration(milliseconds: 500));
  String? token = await FirebaseMessaging.instance.getToken();
  // 后续逻辑...
}

5. 检查Firebase BOM版本兼容性

当前使用的Firebase BOM 31.0.3与你的Flutter Firebase依赖版本是否匹配,建议将BOM版本升级到与依赖兼容的版本,例如:

implementation platform('com.google.firebase:firebase-bom:32.0.0')

同时同步更新Flutter端的Firebase依赖版本到对应兼容版。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 20:55:17