Flutter Firebase云函数交互插件firebase_functions_interop的使用
Flutter Firebase云函数交互插件firebase_functions_interop的使用
简介
firebase_functions_interop 提供了 Firebase Functions Node.js SDK 的互操作层。通过此库,您可以使用 Dart 编写 Firebase Cloud 函数,并在 Node.js 中运行它们。这是一个早期开发预览版本,属于开源项目。
使用
1.0.0-dev.*版本?请参阅UPGRADING.md 了解详细的变更和升级说明。
什么是这个?
firebase_functions_interop 提供了 Firebase Functions Node.js SDK 的互操作层。使用此库编写的 Firebase 函数必须编译为 JavaScript 并在 Node.js 中运行。幸运的是,许多互操作细节都由该库和 Dart SDK 的工具集处理。
以下是一个简单的 “Hello World” HTTPS 云函数示例:
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() {
functions['helloWorld'] = functions.https.onRequest(helloWorld);
}
void helloWorld(ExpressHttpRequest request) {
request.response.writeln('Hello world');
request.response.close();
}
状态
版本 1.0.0 被认为是稳定的,但尚未功能完整。以下是按命名空间实现的功能状态报告:
- ✅ functions
- ✅ functions.config
- ❌ functions.analytics
- ✅ functions.auth
- ✅ functions.firestore 🔥
- ✅ functions.database
- ✅ functions.https
- ✅ functions.pubsub
- ✅ functions.storage
- ❌ functions.remoteConfig
使用方法
1. 创建初始项目
确保已安装 Firebase CLI 以及 Firebase 帐户和测试应用。更多详细信息请参阅Firebase 函数入门。
$ mkdir myproject
$ cd myproject
$ firebase init functions
这将在您的项目的根目录下创建一个 functions 子目录,其中包含标准的 Node.js 包结构,包括 package.json 和 index.js 文件。
2. 初始化 Dart 项目
进入 functions 子目录并添加以下内容的 pubspec.yaml 文件:
name: myproject_functions
description: My project functions
version: 0.0.1
environment:
sdk: '>=2.0.0-dev <3.0.0'
dependencies:
# Firebase Functions 绑定
firebase_functions_interop: ^1.0.0
dev_dependencies:
# 需要将 Dart 编译为有效的 Node.js 模块。
build_runner: ^1.0.0
build_node_compilers: ^0.2.0
然后运行 pub get 来安装依赖项。
3. 编写基本函数
创建 functions/node/index.dart 文件并输入类似以下内容:
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() {
functions['helloWorld'] = functions.https.onRequest(helloWorld);
}
void helloWorld(ExpressHttpRequest request) {
request.response.writeln('Hello world');
request.response.close();
}
复制粘贴也可以。
4. 构建您的函数
此库的版本 1.0.0 依赖于 Dart 2 和新的 build_runner 包。build_node_compilers 包提供了与 dart2js 和 DDC 编译器的集成,该包应该已经存在于 pubspec.yaml 文件的 dev_dependencies 中(见步骤 2)。
创建 functions/build.yaml 文件,内容如下:
targets:
$default:
sources:
- "node/**"
- "lib/**"
builders:
build_node_compilers|entrypoint:
generate_for:
- node/**
options:
compiler: dart2js
# 列出任何 dart2js 特定参数,或省略。
dart2js_args:
- --minify
默认情况下,
build_runner使用 DDC 编译,而此时此库不支持它。上述配置使其使用 dart2js 编译 Dart。
构建命令如下:
$ cd functions
$ pub run build_runner build --output=build
5. 部署
pub run 的结果位于 functions/build/node/index.dart.js。
在您的 functions/package.json 文件中,将 main 字段设置为指向此文件:
{
"...": "...",
"main": "build/node/index.dart.js"
}
或者,您可以替换默认的 index.js 文件:
$ cp functions/build/node/index.dart.js functions/index.js
使用 Firebase CLI 进行部署:
$ firebase deploy --only functions
6. 测试
您可以导航到部署命令打印的新 HTTPS 函数的 URL。对于 Realtime Database 函数,登录到 Firebase 控制台并尝试更改 /messages/{randomValue}/original 下的值。
7. 脚本(可选)
您可以使用 NPM 脚本来简化服务和部署函数的工作流。
更新您的 functions/package.json 文件,如下所示:
{
"...": "...",
"scripts": {
"build": "pub run build_runner build --output=build",
"watch": "pub run build_runner watch --output=build",
"preserve": "npm run build",
"serve": "firebase serve --only functions",
"predeploy": "npm run build",
"deploy": "firebase deploy --only functions",
"preshell": "npm run build",
"shell": "firebase experimental:functions:shell",
"...": "..."
}
}
示例
HTTPS 函数
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() {
functions['helloWorld'] = functions.https.onRequest(helloWorld);
}
void helloWorld(ExpressHttpRequest request) {
request.response.writeln('Hello world');
request.response.close();
}
Realtime Database 函数
void main() {
functions['makeUppercase'] =
functions.database.ref('/messages/{messageId}/original').onWrite(makeUppercase);
}
FutureOr<void> makeUppercase(
Change<DataSnapshot<String>> change, EventContext context) {
final DataSnapshot<String> snapshot = change.after;
var original = snapshot.val();
var pushId = context.params['testId'];
print('Uppercasing $original');
var uppercase = pushId.toString() + ': ' + original.toUpperCase();
return snapshot.ref.parent.child('uppercase').setValue(uppercase);
}
Firestore 函数
void main() {
functions['makeNamesUppercase'] = functions.firestore
.document('/users/{userId}').onWrite(makeNamesUppercase);
}
FutureOr<void> makeNamesUppercase(Change<DocumentSnapshot> change, EventContext context) {
// 由于这是同一文档的更新,我们必须防止此函数写入、读取和再次写入导致无限循环。
final snapshot = change.after;
if (snapshot.data.getString("uppercasedName") == null) {
var original = snapshot.data.getString("name");
print('Uppercasing $original');
UpdateData newData = new UpdateData();
newData.setString("uppercasedName", original.toUpperCase());
return snapshot.reference.updateData(newData);
}
return null;
}
Pubsub 函数
void main() {
functions['logPubsub'] =
functions.pubsub.topic('my-topic').onPublish(logPubsub);
}
void logPubsub(Message message, EventContext context) {
print(message.json["name"]);
}
Storage 函数
void main() {
functions['logStorage'] = functions.storage.object().onChange(logStorage);
}
void logStorage(ObjectMetadata data, EventContext context) {
print(data.name);
}
Auth 函数
void main() {
functions['logAuth'] = functions.auth.user().onCreate(logAuth);
}
void logAuth(UserRecord data, EventContext context) {
print(data.email);
}
配置
Firebase SDK 提供了一种从 Firebase 函数中设置和访问环境变量的方法。
环境变量通过 Firebase CLI 设置,例如:
firebase functions:config:set some_service.api_key="secret" some_service.url="https://api.example.com"
有关更多详细信息,请参阅Firebase 文档。
要在 Firebase 函数中读取这些值,请使用 functions.config。
以下示例还使用了a package node_http 包,它提供了由 Node.js I/O 提供支持的 HTTP 客户端。
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
import 'package:node_http/node_http.dart' as http;
void main() {
functions['helloWorld'] = functions.https.onRequest(helloWorld);
}
void helloWorld(ExpressHttpRequest request) async {
/// 获取环境配置
final config = functions.config;
final String serviceKey = config.get('someservice.key');
final String serviceUrl = config.get('someservice.url');
/// `http.get()` 函数由 `node_http` 包提供。
var response = await http.get("$serviceUrl?apiKey=$serviceKey");
// 对响应执行某些操作,例如将响应体转发给客户端:
request.response.write(response.body);
request.response.close();
}
更多关于Flutter Firebase云函数交互插件firebase_functions_interop的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Firebase云函数交互插件firebase_functions_interop的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
firebase_functions_interop 是一个用于在 Dart 中与 Firebase Cloud Functions 进行交互的插件。它允许你在 Dart 代码中调用 Firebase Cloud Functions,并处理返回的结果。这个插件通常用于 Flutter 应用程序中,以便与 Firebase 后端进行通信。
安装
首先,你需要在 pubspec.yaml 文件中添加 firebase_functions_interop 依赖:
dependencies:
flutter:
sdk: flutter
firebase_functions_interop: ^1.0.0
然后运行 flutter pub get 来安装依赖。
初始化 Firebase
在使用 firebase_functions_interop 之前,你需要确保 Firebase 已经在你的 Flutter 应用程序中初始化。通常,你可以在 main.dart 文件中进行初始化:
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
使用 firebase_functions_interop
1. 导入包
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
2. 创建 Firebase Functions 实例
final functions = FirebaseFunctions.instance;
3. 调用云函数
假设你有一个名为 myFunction 的 Firebase Cloud Function,你可以这样调用它:
void callMyFunction() async {
try {
final result = await functions.httpsCallable('myFunction').call();
print('Function result: ${result.data}');
} catch (e) {
print('Error calling function: $e');
}
}
4. 传递参数
你可以通过 call 方法传递参数给云函数:
void callMyFunctionWithParams() async {
try {
final result = await functions.httpsCallable('myFunction').call({
'param1': 'value1',
'param2': 'value2',
});
print('Function result: ${result.data}');
} catch (e) {
print('Error calling function: $e');
}
}
5. 处理返回结果
云函数的返回结果可以通过 result.data 访问。你可以根据返回的数据类型进行处理。
示例
以下是一个完整的示例,展示了如何在 Flutter 应用程序中使用 firebase_functions_interop 调用 Firebase Cloud Function:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Firebase Functions Example'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
callMyFunction();
},
child: Text('Call My Function'),
),
),
),
);
}
}
void callMyFunction() async {
final functions = FirebaseFunctions.instance;
try {
final result = await functions.httpsCallable('myFunction').call({
'param1': 'value1',
'param2': 'value2',
});
print('Function result: ${result.data}');
} catch (e) {
print('Error calling function: $e');
}
}

