@effect-firebase/admin

中文文档
1.0.1发布于 2026/10/08MITTypeScriptES Module构建来源已验证近 30 天下载 3306

Firebase Admin SDK集成,用于效应Firebase. 规定 a FirestoreService 执行和云函数触发效果包.

中文使用文档
文档目录15 节
  1. 安装
  2. 设置
  3. 云函数
  4. HTTP (英语: onRequest (中文(简体) )
  5. 可调用( N) onCall (中文(简体) )
  6. 可流调( N) onCall + 键 sendChunk (中文(简体) )
  7. 火炉触发器
  8. Pub/Sub (中文(简体) ) onMessagePublished (中文(简体) )
  9. 云层任务( O) onTaskDispatched (中文(简体) )
  10. 计划 onSchedule (中文(简体) )
  11. 设置出错( E) onSetupError (中文(简体) )
  12. 预期拒绝和缺陷记录
  13. 云记录
  14. 解决问题
  15. 许可证

@ effect- firebase/ admin (英语)

Firebase Admin SDK集成,用于效应Firebase. 规定 a FirestoreService 执行和云函数触发效果包.

安装

npm install @effect-firebase/admin effect-firebase effect
npm install firebase-admin firebase-functions express

设置

从一层创建运行时间并将其传递给函数处理器 :

import { initializeApp } from 'firebase-admin/app';
import { Admin, FunctionsRuntime } from '@effect-firebase/admin';

const runtime = FunctionsRuntime.make(Admin.layer({ app: initializeApp() }));

Admin.layer 接受 { app }, (中文(简体) ), { firestore },或者没有参数(使用/初始化默认应用). 它规定 FirestoreService 并接通了"云寻". FunctionsRuntime.Default(app?) 是一个缩写 make(Admin.layer(...))。 。 。 . make 处理运行时间 SIGINT编号 :SIGTERM。 。 。 .

存储器只是需要的效果 FirestoreService这样 yield* PostRepository 在操作员内部工作,却不提供其他东西.

云函数

HTTP (英语:onRequest(中文(简体) )

import { onRequestEffect } from '@effect-firebase/admin';
import { Query } from 'effect-firebase';

export const myFunction = onRequestEffect({ runtime }, (request, response) =>
  Effect.gen(function* () {
    const repo = yield* PostRepository;
    response.json({ posts: yield* repo.query(Query.limit(20)) });
  }),
);

可调用( N)onCall(中文(简体) )

import { onCallEffect } from '@effect-firebase/admin';
import { Schema } from 'effect';

const Input = Schema.Struct({ title: Schema.String, content: Schema.String });
const Output = Schema.Struct({ postId: Schema.String });

export const createPost = onCallEffect(
  { runtime, inputSchema: Input, outputSchema: Output },
  (input) =>
    Effect.gen(function* () {
      const repo = yield* PostRepository;
      const postId = yield* repo.add({ ...input, status: 'draft' });
      return { postId };
    }),
);

何时 inputSchema 财务报告和审定财务报表 outputSchema 自动处理解码和编码.

何时 inputSchema 设置, 处理器收到 (input, context)· ; context 曝光情况 auth, (中文(简体) ), app, (中文(简体) ), rawRequest, (中文(简体) ), instanceIdToken, (中文(简体) ), acceptsStreaming 当 客户端已调用 httpsCallable(...).stream(),则 response 手动对象 sendChunk 打电话 无 inputSchema,处理器接收原始 (request, response)。 。 。 .

onRequestEffect 采取同样做法: bodySchema 处理器收到 (body, request, response); 与 responseSchema 它返回编码和发送的值(状态) successStatus默认值 200) (中文(简体) ).

可流调( N)onCall + 键 sendChunk(中文(简体) )

onCallStreamEffect 需要一个处理器返回 a Stream。每个元素的编码为: chunkSchema 并发送到客户端 response.sendChunk 因为它是生产的。 当 溪流完成, 收集的块作为可调用的最后块返回 data,所以一个 调用此函数的客户端 .stream() 仍然得到全部结果。 溪流是 当客户端断开时中断,包括飞行中拉出.

import { onCallStreamEffect } from '@effect-firebase/admin';
import { Schema, Stream } from 'effect';
import { LanguageModel } from 'effect/ai';

export const chat = onCallStreamEffect(
  {
    runtime,
    timeoutSeconds: 540,
    inputSchema: Schema.Struct({ prompt: Schema.String }),
    chunkSchema: Schema.Struct({ delta: Schema.String }),
  },
  (input) =>
    LanguageModel.streamText({ prompt: input.prompt }).pipe(
      Stream.filter((part) => part.type === 'text-delta'),
      Stream.map((part) => ({ delta: part.delta })),
      Stream.provide(AnthropicModel), // any Effect AI provider layer
    ),
);

客户端 :

const { stream, data } = await httpsCallable(functions, 'chat').stream({
  prompt,
});
for await (const chunk of stream) append(chunk.delta);
const allChunks = await data; // ReadonlyArray<{ delta: string }>

流式调用需要 2 gen 云函数; set timeoutSeconds 足够高 历代相传.

测试可调用设备

CallableFunction.stream() 火场的功能还是根茎,所以 @effect-firebase/admin 以假充名的船舶 CallableResponse数字 :

import {
  runCallable,
  streamCallable,
  makeCallableRequest,
} from '@effect-firebase/admin';

const { stream, data, abort } = streamCallable(chat, { prompt: 'hi' });
for await (const chunk of stream) chunks.push(chunk); // what the client would see
expect(await data).toEqual(chunks); // final `data`
abort(); // simulate a client disconnect

await runCallable(chat, { prompt: 'hi' }); // non-streaming client, final `data` only

// full control over auth/app/rawRequest
streamCallable(
  chat,
  makeCallableRequest(
    { prompt: 'hi' },
    { auth: { uid: 'u1', token, rawToken: 'test-token' } },
  ),
);

火炉触发器

import {
  onDocumentCreatedEffect,
  onDocumentUpdatedEffect,
  onDocumentDeletedEffect,
  onDocumentWrittenEffect,
} from '@effect-firebase/admin';

export const onPostCreated = onDocumentCreatedEffect(
  { runtime, document: 'posts/{postId}', schema: PostModel, idField: 'id' },
  (post) => Effect.log(`Created: ${post.id}`),
);

Firestore 触发处理器必须返回 Effect<void, never, R>: 自己处理或记录每个故障. onDocumentUpdatedEffect 通过 a TypedChange<A> (单位:千美元){ before, after }, (中文(简体) ), onDocumentWrittenEffect (单位:千美元) TypedWrittenChange<A> (单位:千美元){ before: Option<A>, after: Option<A> }) (中文(简体) ). 每个触发器也有一个 ...WithAuthContextEffect 变体(例如:. onDocumentCreatedWithAuthContextEffect(其操作者收到) (event, data)。 。 。 .

Pub/Sub (中文(简体) )onMessagePublished(中文(简体) )

import { onMessagePublishedEffect } from '@effect-firebase/admin';

const MessageSchema = Schema.Struct({ userId: Schema.String });

export const onMessage = onMessagePublishedEffect(
  { runtime, topic: 'my-topic', messageSchema: MessageSchema },
  (message) => Effect.log(`Received for user: ${message.userId}`),
);

云层任务( O)onTaskDispatched(中文(简体) )

import { onTaskDispatchedEffect } from '@effect-firebase/admin';

const TaskSchema = Schema.Struct({ email: Schema.String });

export const processEmail = onTaskDispatchedEffect(
  { runtime, retryConfig: { maxAttempts: 5 }, schema: TaskSchema },
  (task) => Effect.log(`Sending to: ${task.email}`),
);

计划onSchedule(中文(简体) )

import { onScheduleEffect } from '@effect-firebase/admin';

export const cleanup = onScheduleEffect(
  { runtime, schedule: 'every 24 hours' },
  (event) => Effect.log(`Running cleanup job: ${event.jobName}`),
);

设置出错( E)onSetupError(中文(简体) )

每个包装器解码输入的数据,并用你的计划编码输出的数据 声明 当失败时——调用者发送的数据不匹配 inputSchema页:1 文档不匹配 schema - 包装器升起一个 FunctionSetupError 携带 页:1 phase 失败( e)decode-input, (中文(简体) ), encode-output, (中文(简体) ), decode-body, (中文(简体) ), encode-response, (中文(简体) ), decode-document, (中文(简体) ), decode-message, (中文(简体) ), decode-task)和 基础失败, 如 cause (通常为a) SchemaError; 平原 Error 当一个pub/Sub时 有效有效载荷为JSON). FunctionSetupError 财务报告和审定财务报表 isFunctionSetupError 导出.

过 onSetupError 以回收代替默认:

import { onCallEffect } from '@effect-firebase/admin';
import { HttpsError } from 'firebase-functions/https';

export const createPost = onCallEffect(
  {
    runtime,
    inputSchema: Input,
    outputSchema: Output,
    onSetupError: (error, request) =>
      Effect.fail(new HttpsError('invalid-argument', error.cause.message)),
  },
  (input, context) => handle(input, context),
);

钩子接收包装器的本地参数, 所以一个 HTTP 处理器可以自己写 反应和触发器可以检查事件:

export const onPostCreated = onDocumentCreatedEffect(
  {
    runtime,
    document: 'posts/{postId}',
    schema: PostModel,
    onSetupError: (error, event) =>
      Effect.logWarning(`Skipping malformed post ${event.params.postId}`),
  },
  (post) => handle(post),
);

默认时间 onSetupError 省略:

包装无效的数据编码失败
onCallEffectHttpsError('invalid-argument', ...)HttpsError('internal')
onCallStreamEffectHttpsError('invalid-argument', ...)HttpsError('internal')
onRequestEffect400 { error: 'Invalid request body' }500
火炉 / Pub/Sub已登录缺陷( 无重试)—— 说
任务已登记缺陷,重推(重审)—— 说

onCallStreamEffect 不暴露一个 onSetupError 选项,因此其上行是无条件的;其他包装则允许 onSetupError 覆盖这些默认值 .

onCallEffect 财务报告和审定财务报表 onCallStreamEffect 还宣传任何 HttpsError 处理器本身失败到 客户端的代码和信件完整,所以 Effect.catchTag(...) 链条结束于 Effect.fail(new HttpsError(...)) 以书面形式工作.

回收只覆盖边界 。 您的处理器升起的错误从未经过 onSetupError 包括: FunctionSetupError 你养活自己 所以两个留下来 可以区分.

预期拒绝和缺陷记录

单位 onCallEffect, (中文(简体) ), onCallStreamEffect 财务报告和审定财务报表 onRequestEffect,一个可以逃出 处理器被记录为缺陷,除非它是预期的拒绝: HttpsError,或任何 带有 Effect 注释的错误 ErrorReporter.ignore (《公约》) HttpApiError.BadRequest 并使用朋友. onRequestEffect 仍然响应 500; 仅 日志行被跳过 。 触发包装符( Firestore、 Pub/ Sub、 任务、 时间表) 日志 逃出错误 。 任务和计划处理器在日志后重播, 所以重试 配置适用。 对于可调用和 HTTP 处理器,请注释您自己的错误以保存它们 出自缺陷日志, 但仍无法通过调用 :

import { Data, ErrorReporter } from 'effect';

class RejectedError extends Data.TaggedError('RejectedError')<{
  readonly reason: string;
}> {
  readonly [ErrorReporter.ignore] = true;
}

云记录

Admin.layer 自动将默认效果日志替换为将结构化日志写入 Cloud 日志的日志 :

Effect.gen(function* () {
  yield* Effect.log('info message');
  yield* Effect.logError('error message');
}).pipe(Effect.provide(Admin.layer({ app: initializeApp() })));

跟踪的平地物体成为条目 jsonPayload,如同 firebase-functions自己的记录器。 日志说明、日志长度和原因合并为同一有效载荷:

Effect.logError('Could not add order', cause, { partnerId }).pipe(
  Effect.annotateLogs({ orderId }),
  Effect.withLogSpan('checkout'),
);
// jsonPayload: { orderId, partnerId, logSpans: { checkout: 12 }, cause: '<Cause.pretty>' }
  • 在密钥相撞时,明确的后导对象胜过说明.
  • 当原因倒塌到一个 Error,其堆栈被附加到 message,因此错误 报告分组 真实错误 而不是内部合成的堆栈 firebase-functions其它原因都印得漂亮.
  • 有效载荷值为 JSON 安全, 并带有效果 Formatter.formatJson (大写,错误,循环引用, Redacted); 仍然无法序列化的值被替换为 '[Unserializable]'。 。 。 .

伐木机也可以单独使用,作为 Logger.cloudConsole 层.

解决问题

Failed to initialize Google Cloud Firestore client with the available credentials 通常由多个安装的复制件造成 firebase-admin或加以去除(pnpm why firebase-admin)或直接通过 Firestore 实例:

import { getFirestore } from 'firebase-admin/firestore';

const db = getFirestore(initializeApp());
const runtime = FunctionsRuntime.make(Admin.layer({ firestore: db }));

许可证

麻省理工学院

版本与发布记录

@effect-firebase/admin 共发布 40 个版本,首次发布于 2025/10/10;过去 12 个月发布了 39 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.1latest2026/10/081 个月前
1.0.02026/10/051 个月前
1.0.0-beta.9beta2026/09/231 个月前
1.0.0-beta.82026/09/211 个月前
1.0.0-beta.72026/09/141 个月前
1.0.0-beta.62026/09/112 个月前

关于 @effect-firebase/admin 的常见问题

@effect-firebase/admin 是什么?

Firebase Admin SDK集成,用于效应Firebase. 规定 a FirestoreService 执行和云函数触发效果包.

如何安装 @effect-firebase/admin?

在项目目录运行 npm install @effect-firebase/admin,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(^4.0.0)、express(^5.2.1)、firebase-admin(^14.3.0)、effect-firebase(1.0.1)、firebase-functions(^7.3.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effect-firebase/admin 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@effect-firebase/admin 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@effect-firebase/admin 可以商用吗?

@effect-firebase/admin 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@effect-firebase/admin 的下载量有多少?

根据 npm 官方下载统计,@effect-firebase/admin 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,306 次,日均约 110 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@effect-firebase/admin 还在维护吗?

最新版本 1.0.1 发布于 2026/10/08(1 个月前);至今共发布 40 个版本,其中过去 12 个月发布了 39 个;首次发布于 2025/10/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。