簡體   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