繁体   English   中英

如何在模拟器演示项目中使用 FlutterFire?

[英]How do I use FlutterFire with a emulator demo project?

我正在使用带有演示项目的 firebase 模拟器,没有创建任何实际的 firebase 项目资源。 我正在使用以下命令执行此操作...

firebase emulators:start --project demo-test --only firestore

这成功地在 localhost:8080 启动了一个 Firebase 模拟器实例。

然后我在我的颤振应用程序中连接到firebase,如下所示......

await Firebase.initializeApp();
FirebaseFirestore.instance.settings = const Settings(
  host: 'localhost:8080',
  sslEnabled: false,
  persistenceEnabled: false,
);

运行 initializeApp 时,出现以下错误...

E/flutter ( 7724): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: [core/not-initialized] Firebase has not been correctly initialized.
E/flutter ( 7724):
E/flutter ( 7724): Usually this means you've attempted to use a Firebase service before calling `Firebase.initializeApp`.
E/flutter ( 7724):
E/flutter ( 7724): View the documentation for more information: https://firebase.flutter.dev/docs/overview#initialization
E/flutter ( 7724):
E/flutter ( 7724): #0      MethodChannelFirebase.initializeApp
package:firebase_core_platform_interface/…/method_channel/method_channel_firebase.dart:113
E/flutter ( 7724): <asynchronous suspension>
E/flutter ( 7724): #1      Firebase.initializeApp
package:firebase_core/src/firebase.dart:40
E/flutter ( 7724): <asynchronous suspension>
E/flutter ( 7724): #2      _MyHomePageState._asyncInit
package:mobile_app/main.dart:53
E/flutter ( 7724): <asynchronous suspension>
E/flutter ( 7724):

我当前的应用程序具有扩展InheritedWidget的 AppConfig 类,该类在使用时保持实例可用。

你可以试试

class AppConfig extends InheritedWidget {

    static AppConfig? of(BuildContext context) {
        initializeFirebase();
        return context.dependOnInheritedWidgetOfExactType<AppConfig>();
      }
    
    static Future<void> initializeFirebase() async {
        try {
          await Firebase.initializeApp();
        } catch (e) {}
      }
}

您需要在 main() 中初始化 AppConfig()

  1. 尝试在 firebase 命令行和您的应用程序中将localhost更改为您的机器 ip。 有些模拟器,比如ios模拟器,无法理解localhost。
  2. 请粘贴完全可重现的样本,而不是仅粘贴部分行。
  3. 尝试await Firebase.initializeApp(); main函数内部,而不是initState
  4. 首先手动检查8080端口,看看firebase服务器是否真的工作

从技术上讲,问题不在于模拟器。 这里的代码有两个问题。

问题一:模拟器连接不正确

为 Firestore Settingshost参数提供 'localhost:8080'并不是要求FlutterFire 使用模拟器。 使用 Firestore 模拟器的正确方法是

FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);

您可以将该调用包装在一个针对!kReleaseMode进行检查的 if 语句中,这样您在构建应用程序时就不需要将其注释掉。 记得导入flutter/foundation.dart

问题 2:没有提供FirebaseOptions

以下错误:

E/flutter(7724):[错误:flutter/lib/ui/ui_dart_state.cc(198)] 未处理的异常:[core/not-initialized] Firebase 尚未正确初始化。

是由您的Firebase.initializeApp()语句引起的。

Firebase.initializeApp()接受一个可选的命名options参数,其值为FirebaseOptions类型(带有apiKeyappIdprojectId等参数),而您没有提供它。

每个平台(android、ios 和 web)的FirebaseOptions在给定项目的 Firebase 控制台中可用。 没有自己的配置或 FirebaseOptions 的任何客户端都无法初始化FirebaseOptions

要在 Flutter 项目中设置 Firebase,您需要在该 Flutter 项目文件夹中运行flutterfire configure命令。 该命令将要求您从 Firebase 控制台中选择一个项目。 然后,该命令将为每个平台获取配置或FirebaseOptions ,并通过firebase_options.dart文件中的 currentPlatform 的一些 switch 语句使它们可用。

然后,您必须在main.dart中导入此文件,并根据文档使用给定平台的选项调用initializeApp

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

请注意,如果您尚未创建应用,该命令还可以在 Firebase 项目中为您创建应用。

让我们更深入地了解

options参数是可选的,但在技术上是必需的。 如果您查看Firebase.initializeApp()的源代码,您会发现它在底层调用了运行 Flutter 的底层平台(android、ios 或 web)的 MethodChannel 调用。 因此,如果在没有options的情况下调用此 MethodChannel,则会抛出一些coreNotInitialized()

以下是从这里

// If there is no native default app and the user didn't provide options to
// create one, throw.
if (defaultApp == null && _options == null) {
  throw coreNotInitialized();
}

此片段来自method_channel_firebase.dart文件中的initializeApp方法。

在这一步之前有一个条件块,它检查当前平台是否为 android 以及是否有可从原生 android 资源获得的默认 firebase 应用程序。 这可能解释了为什么options (以及name )在高级暴露包中是可选的。

深入思考,您必须Firebase.initializeApp()提供FirebaseOptions是有道理的。 如果您正在为特定平台进行编码,并且要集成 Firebase 或使用其任何服务,则必须以一种或另一种方式提供这些选项。 事实上,对于 Flutter,在过去,当flutterfire命令尚不可用时,必须为每个平台手动设置 Firebase for Flutter(在其自己的文件夹中)。

现在可以直接在main.dart文件中使用 Dart-only Firebase 设置,它仍然需要为每个平台提供FirebaseOptions 这就是flutterfire CLI 在设置过程中所做的事情。 它获取每个平台的配置并导入它们。 事实上, 文档还指定您应该在添加特定的 Firebase 产品插件后运行flutterfire configure

解决方案

因此很明显,要使用任何客户端,您必须从 Firebase 控制台正确连接 Firebase 项目,因为客户端需要项目的配置或FirebaseOptions

由于您想使用演示内容,请使用 firebase 控制台中的“探索演示项目”功能。 这将创建一个有效的临时 Firebase 项目。

然后当你运行flutterfire configure命令时,你选择这个演示项目并使用它。

此外,Firebase 模拟器不使用生产资源。 因此,当您使用--only firestore启动模拟器时,firestore 调用将全部在本地完成。 也就是说,如果您使用有效的 Firebase 项目配置 FlutterFire,并使用 firestore 模拟器,那么您无需担心与生产 API 交互。

请注意,您可以将控制台演示项目与 Firebase 服务的任何模拟器一起使用。 但请记住,这些服务(例如 firestore)本身并未在演示项目中启用,因此如果您尝试针对演示项目的生产 firestore 测试代码,它将无法正常工作。

此外,您必须在使用 Firebase 控制台时查看演示项目。 顶部有一个“退出项目”按钮。 一旦存在,您就丢失了演示项目,可能必须再次从主屏幕单击“探索演示项目”才能访问另一个演示项目

回顾

因此,请确保您的主要方法如下所示:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
  runApp(const MyApp());
}

即使您使用的是演示模拟器,它现在也应该可以按预期工作。

在 main() 里面,你可以这样写 initilize :

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

和其他你必须写的东西:

在底部的 android/app/build.gradle 文件中

apply plugin: 'com.google.gms.google-services'

试试这个。

[编辑]

您可以查看此 github 帖子,因为问题也已从 Flutter 中接受: https ://github.com/firebase/flutterfire/issues/8898

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM