Flutter云函数调用插件dart_firebase_functions的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter云函数调用插件dart_firebase_functions的使用

⚠️ 请注意,这个项目仍处于早期阶段,因此可能包含错误并且会频繁发生重大更改。

动机

该项目旨在通过使用 functions_frameworkdart_firebase_admin 包,在 Dart 中提供类似于 Node.js 的 firebase-functions 包的功能。

如何使用

安装

请在您的 Flutter 应用程序的 pubspec.yaml 文件中添加以下内容:

dependencies:
  dart_firebase_admin: latest
  dart_firebase_functions: latest
  functions_framework: latest
  shelf:

dev_dependencies:
  build_runner:
  dart_firebase_functions_builder: latest
定义 adminApp

在定义函数之前,需要使用您的凭据配置 FirebaseAdminApp

import 'package:dart_firebase_admin/dart_firebase_admin.dart';
import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:functions_framework/functions_framework.dart';

// 初始化 Firebase Admin 应用
final adminApp = FirebaseAdminApp.initializeApp(
  'your-project-id', // 替换为您的项目ID
  Credential.fromServiceAccountParams(
    clientId: 'your-client-id', // 替换为您的客户端ID
    privateKey: 'your-private-key', // 替换为您的私钥
    email: 'your-client-email', // 替换为您的客户端电子邮件
  ),
);

// 初始化 Firestore、Auth 和 Messaging
final firestore = Firestore(adminApp);
final auth = Auth(adminApp);
final messaging = Messaging(adminApp);
定义 HTTP 函数

使用 [@HTTPFunction](/user/HTTPFunction)() 来定义 HTTP 函数。

import 'package:dart_firebase_admin/dart_firebase_admin.dart';
import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:shelf/shelf.dart';

// 初始化 Firebase Admin 应用
FirebaseAdminApp initializeAdminApp() => adminApp;

// 定义一个简单的 HTTP 函数
[@HTTPFunction](/user/HTTPFunction)()
Future<Response> hello(Request request) async => Response.ok('Hello, World!');

然后,运行 build_runner 来生成代码。

dart pub run build_runner build -d

生成的代码如下所示:

// GENERATED CODE - DO NOT MODIFY BY HAND

import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:functions_framework/serve.dart';
import 'package:server/functions.dart' as function_library;

Future<void> main(List<String> args) async {
  final app = function_library.initializeAdminApp();
  FirebaseFunctions.initialize(app);
  await serve(args, _nameToFunctionTarget);
}

FunctionTarget? _nameToFunctionTarget(String name) => switch (name) {
      'hello' => FunctionTarget.http(
          function_library.hello,
        ),
      _ => null
    };
定义 Cloud Firestore 触发的函数

为了定义由 Cloud Firestore 文档创建触发的函数,使用 [@OnDocumentCreated](/user/OnDocumentCreated) 并传递参数,如下例所示。

import 'package:dart_firebase_admin/dart_firebase_admin.dart';
import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:functions_framework/functions_framework.dart';

// 初始化 Firebase Admin 应用
FirebaseAdminApp initializeAdminApp() => adminApp;

// 定义文档创建触发的函数
[@OnDocumentCreated](/user/OnDocumentCreated)('todos/{todoId}')
Future<void> oncreatetodo(
  ({String todoId}) params,
  QueryDocumentSnapshot snapshot,
  RequestContext context,
) async {
  context.logger.debug('todoId: ${params.todoId}');
  final data = snapshot.data();
  final title = data?['title'] as String?;
  await snapshot.ref.update({'title': '$title from server!'});
}

还可以被嵌套文档创建触发。

[@OnDocumentCreated](/user/OnDocumentCreated)('todos/{todoId}/logs/{logId}')
Future<void> oncreatelog(
  ({String todoId, String logId}) params,
  QueryDocumentSnapshot snapshot,
  RequestContext context,
) async {
  final todoId = params.todoId;
  final logId = params.logId;
  final data = snapshot.data();
  context.logger.debug('todoId: $todoId');
  context.logger.debug('logId: $logId');
  context.logger.debug('data: $data');
}

然后,运行 build_runner 来生成代码。

dart pub run build_runner build -d

生成的代码如下所示:

// GENERATED CODE - DO NOT MODIFY BY HAND

import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:functions_framework/serve.dart';
import 'package:server/functions.dart' as function_library;

Future<void> main(List<String> args) async {
  final app = function_library.initializeAdminApp();
  FirebaseFunctions.initialize(app);
  await serve(args, _nameToFunctionTarget);
}

FunctionTarget? _nameToFunctionTarget(String name) => switch (name) {
      'oncreatetodo' => FunctionTarget.cloudEventWithContext((event, context) {
          const pathPattern = 'todos/{todoId}';
          final documentIds =
              FirestorePathParser(pathPattern).parse(event.subject!);
          final data = QueryDocumentSnapshotBuilder(event).fromCloudEvent();
          return function_library.oncreatetodo(
            (todoId: documentIds['todoId']!),
            data.snapshot,
            context,
          );
        }),
      'oncreatelog' => FunctionTarget.cloudEventWithContext((event, context) {
          const pathPattern = 'todos/{todoId}/logs/{logId}';
          final documentIds =
              FirestorePathParser(pathPattern).parse(event.subject!);
          final data = QueryDocumentSnapshotBuilder(event).fromCloudEvent();
          return function_library.oncreatelog(
            (todoId: documentIds['todoId']!, logId: documentIds['logId']!),
            data.snapshot,
            context,
          );
        }),
      _ => null
    };

示例代码

下面是一个完整的示例 demo,展示了如何使用 dart_firebase_functions 插件。

import 'package:dart_firebase_admin/dart_firebase_admin.dart';
import 'package:dart_firebase_functions/dart_firebase_functions.dart';
import 'package:functions_framework/functions_framework.dart';
import 'package:shelf/shelf.dart';

void main() {
  // 初始化 Firebase Admin 应用
  final adminApp = FirebaseAdminApp.initializeApp(
    'your-project-id',
    Credential.fromServiceAccountParams(
      clientId: 'your-client-id',
      privateKey: 'your-private-key',
      email: 'your-client-email',
    ),
  );

  // 定义 HTTP 函数
  [@HTTPFunction](/user/HTTPFunction)()
  Future<Response> hello(Request request) async => Response.ok('Hello, World!');

  // 定义文档创建触发的函数
  [@OnDocumentCreated](/user/OnDocumentCreated)('todos/{todoId}')
  Future<void> oncreatetodo(
    ({String todoId}) params,
    QueryDocumentSnapshot snapshot,
    RequestContext context,
  ) async {
    context.logger.debug('todoId: ${params.todoId}');
    final data = snapshot.data();
    final title = data?['title'] as String?;
    await snapshot.ref.update({'title': '$title from server!'});
  }

  // 启动服务
  FirebaseFunctions.initialize(adminApp);
  print('Server is running...');
}

更多关于Flutter云函数调用插件dart_firebase_functions的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter云函数调用插件dart_firebase_functions的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用dart_firebase_functions插件来调用Cloud Functions的示例代码。这个示例假设你已经配置好了Firebase项目,并且已经在Firebase控制台中创建了一个Cloud Function。

前提条件

  1. Flutter环境:确保你的Flutter环境已经配置好。
  2. Firebase项目:创建一个Firebase项目,并在项目中启用Cloud Functions。
  3. Cloud Function:在Firebase控制台中创建一个简单的Cloud Function。例如,一个返回“Hello, World!”的HTTP触发器函数。

步骤

1. 添加依赖

在你的pubspec.yaml文件中添加dart_firebase_functions依赖:

dependencies:
  flutter:
    sdk: flutter
  dart_firebase_functions: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

2. 配置Firebase

确保你已经按照Firebase的文档配置了google-services.json(Android)和GoogleService-Info.plist(iOS)。

3. 初始化Firebase并调用Cloud Function

在你的Flutter项目中,打开你希望调用Cloud Function的Dart文件(例如main.dart),然后编写如下代码:

import 'package:flutter/material.dart';
import 'package:dart_firebase_functions/dart_firebase_functions.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String result = "";

  @override
  void initState() {
    super.initState();
    // 初始化Firebase并调用Cloud Function
    _callCloudFunction();
  }

  void _callCloudFunction() async {
    // 初始化Firebase Functions实例
    FirebaseFunctions functions = FirebaseFunctions.instance;

    // 定义要传递给Cloud Function的数据
    Map<String, dynamic> data = {
      'message': 'Hello from Flutter!',
    };

    try {
      // 调用Cloud Function
      HttpsCallableResult callableResult = await functions.httpsCallable('yourFunctionName').call(data);

      // 处理Cloud Function的返回结果
      if (callableResult.data != null) {
        setState(() {
          result = callableResult.data['message'] ?? 'No message returned';
        });
      } else {
        setState(() {
          result = 'No data returned from Cloud Function';
        });
      }
    } catch (e) {
      // 处理错误
      setState(() {
        result = 'Error calling Cloud Function: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Cloud Functions Example'),
        ),
        body: Center(
          child: Text(result),
        ),
      ),
    );
  }
}

在上面的代码中:

  • FirebaseFunctions.instance用于获取Firebase Functions的实例。
  • httpsCallable('yourFunctionName')用于指定你要调用的Cloud Function的名称(请替换为你实际的Cloud Function名称)。
  • call(data)方法用于传递数据给Cloud Function。
  • callableResult.data包含了Cloud Function返回的数据。

4. 运行你的Flutter应用

确保你已经连接了设备或启动了模拟器,然后运行flutter run来启动你的Flutter应用。你应该能够看到从Cloud Function返回的消息。

注意事项

  • 确保你的Cloud Function已经正确部署,并且是可访问的。
  • 确保你的Firebase项目配置正确,包括正确的区域设置和API密钥。
  • 如果有权限问题,请检查你的Firebase项目权限设置,确保你的应用有权调用Cloud Functions。

通过以上步骤,你应该能够在Flutter项目中成功调用Firebase Cloud Functions。

回到顶部