如何在 Firebase Emulator Suite 环境中的 Flutter 前端应用程序中调用 Firebase 函数 httpCallable?

问题描述 投票:0回答:1

我已经设置了 Firebase Emulator Suite,并且数据库触发的功能按预期工作。但是,我在模拟器环境中的 Flutter 前端应用程序中使用 httpsCallable 调用 Firebase 函数时遇到问题。功能好像没有反应,不知道是配置问题还是其他问题。

在此输入图片描述

确保 Firebase Emulator Suite 正在运行,并且功能模拟器在端口 5001 上启动。 使用 useFunctionsEmulator('localhost', 5001) 将我的 Flutter 应用程序配置为使用本地模拟器。 已验证数据库触发的函数在模拟器中按预期工作,这表明模拟器运行正常。 尝试从 Flutter 应用程序调用该函数,但它抛出 FirebaseFunctionsException 并显示错误 [firebase_functions/unavailable] 帮助不大。

main.dart

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(...); // I did deliver my option

  FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
  FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001);
  FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
  FirebaseStorage.instance.useStorageEmulator('localhost', 9199);

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Firebase Test App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final FirebaseFunctions functions = FirebaseFunctions.instance;
  String _result = '';

  Future<void> regeneratePIN(String formerPIN) async {
    try {
      final HttpsCallable callable = functions.httpsCallable('replacePIN');
      final response = await callable.call(<String, dynamic>{
        'formerPIN': formerPIN,
      });
      setState(() {
        _result = 'New PIN: ${response.data['newPIN']}';
      });
    } catch (e) {
      setState(() {
        _result = 'Error: $e';
      });

      rethrow;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
              child : TextField(
                onSubmitted: regeneratePIN,
              ),

调试控制台:

FirebaseFunctionsException ([firebase_functions/unavailable] UNAVAILABLE
#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:648:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:334:18)
<asynchronous suspension>
#2      MethodChannelHttpsCallable.call (package:cloud_functions_platform_interface/src/method_channel/method_channel_https_callable.dart:22:24)
<asynchronous suspension>
#3      HttpsCallable.call (package:cloud_functions/src/https_callable.dart:49:37)
<asynchronous suspension>
#4      _MyHomePageState.regeneratePIN (package:sapor_firebase/main.dart:56:24)
<asynchronous suspension>

终端:

PS C:\Users\jose.lee\dev\$PROJ_NAME> firebase emulators:start
(node:17992) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
i  emulators: Starting emulators: auth, functions, firestore, hosting, pubsub, storage
!  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: database, dataconnect
(node:17992) [DEP0044] DeprecationWarning: The `util.isArray` API is deprecated. Please use `Array.isArray()` instead.
i  firestore: Firestore Emulator logging to firestore-debug.log
+  firestore: Firestore Emulator UI websocket is running on 9150.
i  pubsub: Pub/Sub Emulator logging to pubsub-debug.log
i  hosting[my-app]: Serving hosting files from: public
+  hosting[my-app]: Local server: http://127.0.0.1:5000
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "C:\Users\jose.lee\dev$PROJ_NAME\functions" for Cloud Functions...
!  functions: Your requested "node" version "18" doesn't match your global version "22". Using node@22 from host.
Serving at port 8207

(node:14412) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)

+  functions[us-central1-scheduleInactivationForWebEditPIN]: firestore function initialized.
i  functions[us-central1-inactivateWebEditPIN]: function ignored because the pubsub emulator does not exist or is not running.
+  functions[us-central1-replacePIN]: http function initialized (http://127.0.0.1:5001/my-app/us-central1/replacePIN).

┌─────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! It is now safe to connect your app. │
│ i  View Emulator UI at http://127.0.0.1:4000/               │
└─────────────────────────────────────────────────────────────┘

┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator       │ Host:Port      │ View in Emulator UI             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ 127.0.0.1:9099 │ http://127.0.0.1:4000/auth      │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Functions      │ 127.0.0.1:5001 │ http://127.0.0.1:4000/functions │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore      │ 127.0.0.1:8080 │ http://127.0.0.1:4000/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Hosting        │ 127.0.0.1:5000 │ n/a                             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Pub/Sub        │ 127.0.0.1:8085 │ n/a                             │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Storage        │ 127.0.0.1:9199 │ http://127.0.0.1:4000/storage   │
└────────────────┴────────────────┴─────────────────────────────────┘
  Emulator Hub running at 127.0.0.1:4400
  Other reserved ports: 4500, 9150
flutter firebase google-cloud-functions firebase-tools
1个回答
0
投票

从日志看来,您需要启动 pubsub 模拟器,请参阅以下日志项:

函数被忽略,因为 pubsub 模拟器不存在或不存在 跑步。

我们可以在模拟器列表中看到 pubsub 没有运行。


另请注意其他日志项目:

您请求的“节点”版本“18”与您的全局版本不匹配 “22”。从主机使用node@22。

© www.soinside.com 2019 - 2024. All rights reserved.