Firebase Cloud Messaging:平台异常(PlatformException(null-error,主机平台返回非空返回值的空值。,null,null))

42

我正在尝试从一个Node.js API向Flutter应用程序发送通知。首先,我希望我的应用程序能够从Firebase接收通知。

但是,当我调用initializeApp时,出现了问题:

PlatformException (PlatformException(null-error, Host platform returned null value for non-null return value., null, null))

并且,在控制台中显示了这个错误信息:

E/flutter (25357): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(null-error, Host platform returned null value for non-null return value., null, null)
E/flutter (25357): #0      FirebaseCoreHostApi.optionsFromResource (package:firebase_core_platform_interface/src/pigeon/messages.pigeon.dart:250)
package:firebase_core_platform_interface/…/pigeon/messages.pigeon.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #1      MethodChannelFirebase.initializeApp (package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:89)
package:firebase_core_platform_interface/…/method_channel/method_channel_firebase.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #2      Firebase.initializeApp (package:firebase_core/src/firebase.dart:40)
package:firebase_core/src/firebase.dart:1
E/flutter (25357): <asynchronous suspension>
E/flutter (25357): #3      main (package:notifappfcm/main.dart:13)
package:notifappfcm/main.dart:1

我一直在寻找解决这个问题的方法,但我真的找不到。

这是我的应用程序代码:

main.dart

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'mainscreen.dart';

Future<void> _firebadeMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(); // options: DefaultFirebaseConfig.platformOptions
  print('Handling a background message ${message.messageId}');
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  FirebaseMessaging.onBackgroundMessage(_firebadeMessagingBackgroundHandler);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MainScreen(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

 
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

 @override
  void initState() {
    super.initState();
  }

  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

mainscreen.dart

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  late AndroidNotificationChannel channel;
  late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;

  @override
  void initState() {
    super.initState();

    requestPermission();
    loadFCM();
    listenFCM();
    // Get device's notification token
    getToken();
  }


  void getToken() async {
    await FirebaseMessaging.instance.getToken().then((token) => print(token));
  }

  void requestPermission() async {
    FirebaseMessaging messaging = FirebaseMessaging.instance;

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

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      print('User granted permission');
    } else if (settings.authorizationStatus ==
        AuthorizationStatus.provisional) {
      print('User granted provisional permission');
    } else {
      print('User declined or has not accepted permission');
    }
  }

  void listenFCM() async {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification? notification = message.notification;
      AndroidNotification? android = message.notification?.android;
      if (notification != null && android != null && !kIsWeb) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
                android: AndroidNotificationDetails(channel.id, channel.name,
                    // ignore: todo
                    // TODO add a proper drawable resource to android (now using one that already exists)
                    icon: 'launch_background')));
      }
    });
  }

  void loadFCM() async {
    if (!kIsWeb) {
      channel = const AndroidNotificationChannel(
        'high_importance_channel', // id
        'High Importance Notifications', // title
        importance: Importance.high,
        enableVibration: true,
      );

      flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

      /// Create an Android Notification Channel.
      ///
      /// We use this channel in the `AndroidManifest.xml` file to override the
      /// default FCM channel to enable heads up notifications.
      await flutterLocalNotificationsPlugin
          .resolvePlatformSpecificImplementation<
              AndroidFlutterLocalNotificationsPlugin>()
          ?.createNotificationChannel(channel);

      /// Update the iOS foreground notification presentation options to allow
      /// heads up notifications.
      await FirebaseMessaging.instance
          .setForegroundNotificationPresentationOptions(
        alert: true,
        badge: true,
        sound: true,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Container(
        height: 40,
        width: 200,
        color: Colors.red,
      ),
    ));
  }
}

1
遇到相同的问题,有任何解决方法吗? - segun code
我发现了一个问题,我只需要正确地将我的应用程序与Firebase链接起来即可。 第一次做的时候是错误的。 这是一个链接,可以帮助您链接您的应用程序和FCM:https://firebase.google.com/docs/flutter/setup?platform=android附注:请完整地按照教程操作,我第一次没有这样做,这就是为什么我会出现错误的原因^^ - Shiroe
你所说的“正确链接”是什么意思?你能具体说明一下吗? - Agni Gari
要使您的应用程序能够与Firebase通信,您必须在Firebase中注册您的应用程序。 因此,我按照firebase.google.com/docs/flutter/setup?platform=android上的完整教程操作后,我的代码可以正常工作。 我犯的错误是只做了教程的第一部分(没有看到接下来的内容),因此我的应用程序未与Firebase连接。 - Shiroe
在我的情况下,我执行了Flutter clean命令,它正常工作。 - Rahul Kushwaha
16个回答

74

请确保您已在项目级别的build.gradle文件和应用程序级别的build.gradle文件中添加了Firebase SDK依赖项。

需要在项目级别的build.gradle中添加的依赖项:

buildscript {
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }
  dependencies {
    ...
    // Add this line
    classpath 'com.google.gms:google-services:4.3.13'
  }
}

allprojects {
  ...
  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    ...
  }
}

需要在应用级别的 build.gradle 中添加以下依赖项:

apply plugin: 'com.android.application'
// Add this line
apply plugin: 'com.google.gms.google-services'

dependencies {
  // Import the Firebase BoM
  implementation platform('com.google.firebase:firebase-bom:30.2.0')

  // Add the dependency for the Firebase SDK for Google Analytics
  // When using the BoM, don't specify versions in Firebase dependencies
  implementation 'com.google.firebase:firebase-analytics'

  // Add the dependencies for any other desired Firebase products
  // https://firebase.google.com/docs/android/setup#available-libraries
}

3
在Firebase上设置Flutter项目时,默认情况下似乎不会添加这些依赖项。 - MarlonDSC
我已经尝试了所有的方法,但仍然遇到了这个错误。 - undefined

16
注意。按照上述描述手动更改build.gradle文件并不是一个解决方案。要么不起作用,要么每次构建都会生成大量警告,因为使用了过时的依赖项。正确的解决方案是这样的: Firebase应该像下面这样初始化:
await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

为此,您需要从命令行/终端运行一些命令:
// Add firebase core into your project
flutter pub add firebase_core
// Generate firebase options file
flutterfire configure

然后你需要在你的.dart文件中导入这些。
// Import firebase core and generated file
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

详情请参考这里

1
我在main.dart的main()函数中的Firebase.initializeApp中缺少options: DefaultFirebaseOptions.currentPlatform。添加了这个选项后(并导入了使用终端命令flutterfire configure创建的firebase_options.dart文件),它就可以工作了。 - Boommeister
修改build.gradle的所有上述解决方案对我都没有起作用。然而,在Firebase.initializeApp内添加options: DefaultFirebaseOptions.currentPlatform的解决方案对我有效。 - Asad
谢谢。我遇到了同样的异常,这个优雅的解决方案起作用了。 - undefined
这应该是正确的答案。 - undefined

13

确保您在 android/build.gradle 中拥有这些设置

buildscript {

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
  }

  dependencies {
    // ...

    // Add the following line:
    classpath 'com.google.gms:google-services:4.3.13'  // Google Services plugin
  }
}

allprojects {
  // ...

  repositories {
    // Check that you have the following line (if not, add it):
    google()  // Google's Maven repository
    // ...
  }
}

接着在你的android/app/build.gradle文件中:

apply plugin: 'com.android.application'
// Add the following line:
apply plugin: 'com.google.gms.google-services'  // Google Services plugin

android {
  // ...
}

您可以按照这里的步骤操作。

同时,不要忘记从 Firebase 项目控制台下载 google-service.json 文件,并将其放置在 android/app 文件夹中。


虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。- 来自审查 - Lalaluka
@Lalaluka 谢谢提醒。我已经修改了。 - Kurt

5
有时候FlutterFire cli无法更新build.gradle文件,因此会出现上述错误。
在项目级别的build.gradle文件中添加firebase依赖项,如下所示:
   dependencies {
    classpath 'com.android.tools.build:gradle:7.1.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.gms:google-services:4.3.10'
    classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}

在应用级别的build.gradle文件中,应用Firebase插件,如下所示:
    apply plugin: 'com.google.gms.google-services'
    apply plugin: 'com.google.firebase.crashlytics'

5

来自:

await Firebase.initializeApp();

To:

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);

对我来说没问题!


3
我们如何获取DefaultFirebaseOptions.currentPlatform?我找不到它。你能帮我吗? - Rohit Sharma
@RohitSharma,请按照以下说明操作:https://firebase.google.com/docs/flutter/setup?platform=android,在执行`flutterfire configure`之后,它将生成所需的文件,例如lib/firebase_options.dart等。 - undefined

1
这个解决方案非常有效 :)
在项目级别的build.gradle文件中添加Firebase依赖项,如下所示:
dependencies {

    classpath 'com.android.tools.build:gradle:7.1.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath 'com.google.gms:google-services:4.3.10'
    classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
}

在应用程序级别的build.gradle文件中,应用Firebase插件,如下所示:
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

1

看起来你需要在await Firebase.initializeApp();这一行中设置DefaultFirebaseOptions。

根据这个文档,你需要放置选项。

按照以下步骤进行操作:

  1. 运行flutter pub add firebase_core
  2. 运行flutterfire configure。如果您已经配置了项目,请跳过此步骤。
  3. 在您的main.dart中,更新您的代码。

await Firebase.initializeApp();

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  1. 尝试运行您的应用程序

希望这能解决问题。

感谢阅读!


1

被接受的答案仍然有效,但需要手动操作,而且不确定要添加哪个Google Services版本和Firebase BOM。

我建议使用FlutterFire CLI来配置项目并自动设置所有这些build.gradle依赖项。

官方配置设置在此处


1
同其他答案一样,您需要手动设置必要的依赖项,特别是在将我们的Flutter应用程序与Firebase集成后,我们的build.gradle(项目级别和应用级别)没有任何直接更改。
以下是解决问题的简要步骤。
转到您的项目级build.gradle文件,并在文件依赖项中添加以下行。
dependencies {
  classpath 'com.android.tools.build:gradle:7.3.0'
  classpath 'com.google.gms:google-services:4.3.13' // Add this line
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}

之后,转到您的应用级build.gradle文件,并添加以下行。
dependencies {
  implementation platform('com.google.firebase:firebase-bom:30.2.0')
  implementation 'com.google.firebase:firebase-analytics'
}

这将确保我们的Firebase准备好进行开发。
当然。即使您已经添加了这些行或已经配置好了,可能仍然会出现错误。最常见的错误是:
E/flutter (10040): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] 
Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()
E/flutter (10040): #0      MethodChannelFirebase.app 
(package:firebase_core_platform_interface/src/method_channel/method_channel_firebase.dart:149:5)
E/flutter (10040): #1      Firebase.app (package:firebase_core/src/firebase.dart:55:41)
E/flutter (10040): #2      FirebaseMessaging.instance (package:firebase_messaging/src/messaging.dart:32:47)

无论出于什么原因,
未处理的异常:[core/no-app] 未创建 Firebase 应用 '[DEFAULT]' - 调用 Firebase.initializeApp() 错误也与以下内容相关:
未处理的异常:PlatformException(null-error, 主机平台返回了非空返回值的空值, null, null)
在您的情况下也是如此。不过,有一个解决方案可以修复这个问题,那就是在初始化应用程序时简单地添加 DefaultFirebaseOptions
WidgetsFlutterBinding.ensureInitialized();

await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform // Add thiis.
);

0

试试这个

你想要升级到最新版本。所以我使用了以下内容:

flutter channel dev

请将此内容作为回答发布在评论中。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接