使用WorkManager与Firebase发送推送通知时遇初始化错误求助
问题描述
我正在使用Firebase Cloud Messaging发送推送通知,希望通过WorkManager包实现通知调度。之前尝试过flutter_local_notification包的zoneSchedule方法,但该方法会在应用首次启动时就发送通知。现在遇到如下错误:
D/EGL_emulation( 6738): eglCreateContext: 0xe91a9600: maj 2 min 0 rcv 2 D/EGL_emulation( 6738): eglCreateContext: 0xe91a9a60: maj 2 min 0 rcv 2 D/HostConnection( 6738): HostConnection::get() New Host Connection established 0xe919c6a0, tid 6952 D/HostConnection( 6738): HostComposition ext ANDROID_EMU_CHECKSUM_HELPER_v1 ANDROID_EMU_native_sync_v2 ANDROID_EMU_native_sync_v3 ANDROID_EMU_native_sync_v4 ANDROID_EMU_dma_v1 ANDROID_EMU_direct_mem ANDROID_EMU_YUV_Cache ANDROID_EMU_has_shared_slots_host_memory_allocator ANDROID_EMU_sync_buffer_data ANDROID_EMU_read_color_buffer_dma GL_OES_vertex_array_object GL_KHR_texture_compression_astc_ldr ANDROID_EMU_host_side_tracing ANDROID_EMU_gles_max_version_2 D/EGL_emulation( 6738): eglMakeCurrent: 0xe91a9a60: ver 2 0 (tinfo 0xcad2bc10) (first time) E/BackgroundWorker( 6738): errorCode: error, errorMessage: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() I/WM-WorkerWrapper( 6738): Worker result FAILURE for Work [ id=0099bb1f-670e-4711-9fc2-7b95f118ca6e, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
相关代码文件
main.dart
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); await FlutterDownloader.initialize(debug: true); tz.initializeTimeZones(); await Workmanager().initialize(callbackDispatcher,isInDebugMode: true); await GetStorage.init(); runApp(const MyApp()); } @pragma('vm:entry-point') Future<void> backgroundMessageHandler(RemoteMessage message) async { await Firebase.initializeApp(); print("backgroundMessageHandler"); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', locale: HandleLocale().getLocale(), translations: LocaleString(), showSemanticsDebugger: false, debugShowCheckedModeBanner: false, theme: Themes().lightTheme, darkTheme: Themes().darkTheme, themeMode: ThemeServices().getThemeMode(), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { myController controller = Get.put(myController()); @override void initState() { super.initState(); NotificationHandler().getToken().then((value){ print(value); }); Workmanager().registerOneOffTask( '1', 'simpleTask', initialDelay: const Duration(seconds: 10), ); NotificationHandler().initMessage(context); NotificationHandler().interactMessage(context); isAlreadyLoggedIn(); } Future<void> isAlreadyLoggedIn() async { final value = await controller.getUserInfo(); print(value.toList()); if (value.isEmpty) { Navigator.push( context, MaterialPageRoute(builder: (context) => const LoginPage())); } } @override Widget build(BuildContext context) { return const PageHandler(); } }
callbackdispatcher.dart
void callbackDispatcher() { Workmanager().executeTask((taskName, inputData) async { // This is where you can schedule your notifications at the desired time final token = await NotificationHandler().getToken(); NotificationHandler().scheduleNotification(token); return Future.value(true); }); }
根目录build.gradle
buildscript { ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.3.0' classpath"com.google.gms:google-services:4.3.15" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { delete rootProject.buildDir }
android/build.gradle
plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } android { namespace "com.example.income_and_expenditure_app" compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { applicationId "com.example.income_and_expenditure_app" minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion multiDexEnabled true versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { signingConfig signingConfigs.debug } } } flutter { source '../..' } apply plugin:"com.google.gms.google-services" apply plugin:'com.android.application' dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation("com.google.firebase:firebase-analytics-ktx") implementation(platform("com.google.firebase:firebase-bom:32.3.1")) implementation 'com.google.firebase:firebase-auth' }
解决方案
1. 修复Firebase未初始化问题
WorkManager的回调运行在独立的后台隔离区,不会共享主应用的Firebase初始化状态,必须在回调内部重新初始化Firebase:
修改callbackdispatcher.dart:
void callbackDispatcher() { Workmanager().executeTask((taskName, inputData) async { // 后台任务中重新初始化Firebase await Firebase.initializeApp(); // 执行通知逻辑 final token = await NotificationHandler().getToken(); NotificationHandler().scheduleNotification(token); return Future.value(true); }); }
2. 解决flutter_local_notifications的zoneSchedule首次启动触发问题
如果继续使用zoneSchedule,需避免在应用启动时直接调用,可通过本地存储标记是否已调度,或仅在用户交互后触发:
Future<void> setupScheduledNotification() async { final storage = GetStorage(); final isScheduled = storage.read('notification_scheduled') ?? false; if (!isScheduled) { await flutterLocalNotificationsPlugin.zonedSchedule( 0, '通知标题', '通知内容', // 设置目标触发时间,例如明天当前时间 tz.TZDateTime.now(tz.local).add(const Duration(days: 1)), const NotificationDetails( android: AndroidNotificationDetails('schedule_channel', '定时通知'), ), androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, ); storage.write('notification_scheduled', true); } }
3. 依赖兼容性检查
确保flutter_workmanager与Firebase BOM版本兼容,当前配置的Firebase BOM 32.3.1属于稳定版本,无需额外调整。
内容的提问来源于stack exchange,提问作者Jeevan Shrestha
相关产品推荐
相关产品推荐

