{"_id":"@emito/provider-fcm","name":"@emito/provider-fcm","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@emito/provider-fcm","version":"0.1.0","license":"MIT","description":"Firebase Cloud Messaging push provider plugin for Emito.","keywords":["emito","notifications","notification-infrastructure","self-hosted","fcm","firebase","push-notifications","provider","plugin"],"repository":{"type":"git","url":"git+https://github.com/emito-pro/emito.git","directory":"packages/provider-fcm"},"homepage":"https://github.com/emito-pro/emito/tree/main/packages/provider-fcm#readme","bugs":{"url":"https://github.com/emito-pro/emito/issues"},"author":{"name":"SFER LABS LLC"},"engines":{"node":">=22"},"publishConfig":{"access":"public"},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","dependencies":{"firebase-admin":"^13.0.0","zod":"^3.24.0","@emito/provider-kit":"0.1.0","@emito/types":"0.1.0"},"devDependencies":{"@vitest/coverage-v8":"^3.0.0","typescript":"^5.8.0","vitest":"^3.0.0"},"scripts":{"build":"tsc --project tsconfig.build.json","test":"vitest run --coverage","check":"tsc --noEmit","lint":"biome check src/"},"_id":"@emito/provider-fcm@0.1.0","_integrity":"sha512-AAXq75D8F+Ck5t1fsw49ZWe87a+NbibmwyXb2VMx6VVGppu1hxHVuUDJ1Etb8aqkfDkoSV2dDkJNntZ78OTsiQ==","_resolved":"/tmp/71c2533753e7720c3f00e42b2b4c7de3/emito-provider-fcm-0.1.0.tgz","_from":"file:emito-provider-fcm-0.1.0.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-AAXq75D8F+Ck5t1fsw49ZWe87a+NbibmwyXb2VMx6VVGppu1hxHVuUDJ1Etb8aqkfDkoSV2dDkJNntZ78OTsiQ==","shasum":"26380f0989d87a55e4cd52f20f2687324f45f871","tarball":"https://registry.npmjs.org/@emito/provider-fcm/-/provider-fcm-0.1.0.tgz","fileCount":7,"unpackedSize":18381,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCT4U5cMIoYzLKcq7DlKH9SAUpesbdVomTDYzCbN1yIggIgdLKjaVOqj9jUYcktQLNuyHRQ1CH0BMZYUIUaB2/U1M4="}]},"_npmUser":{"name":"dev-emito","email":"dev-npm-emito@sfer.co"},"directories":{},"maintainers":[{"name":"dev-emito","email":"dev-npm-emito@sfer.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/provider-fcm_0.1.0_1787412020692_0.10506493519237026"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-22T15:20:20.613Z","0.1.0":"2026-08-22T15:20:20.859Z","modified":"2026-08-22T15:20:21.011Z"},"maintainers":[{"name":"dev-emito","email":"dev-npm-emito@sfer.co"}],"description":"Firebase Cloud Messaging push provider plugin for Emito.","homepage":"https://github.com/emito-pro/emito/tree/main/packages/provider-fcm#readme","keywords":["emito","notifications","notification-infrastructure","self-hosted","fcm","firebase","push-notifications","provider","plugin"],"repository":{"type":"git","url":"git+https://github.com/emito-pro/emito.git","directory":"packages/provider-fcm"},"author":{"name":"SFER LABS LLC"},"bugs":{"url":"https://github.com/emito-pro/emito/issues"},"license":"MIT","readme":"<div align=\"center\">\n  <img src=\"../../.github/assets/emito-logo.png\" width=\"120\" alt=\"Emito\" />\n\n  # @emito/provider-fcm\n\n  **Firebase Cloud Messaging push provider plugin for Emito.**\n\n  [![License](https://img.shields.io/badge/license-MIT-blue)](../../README.md)\n  [![Types](https://img.shields.io/badge/types-included-blue?logo=typescript&logoColor=white)](#)\n\n  ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)\n  ![Zod](https://img.shields.io/badge/Zod-3E67B1?logo=zod&logoColor=white)\n</div>\n\n## What it is\n\n`@emito/provider-fcm` is a push delivery adapter that sends Emito notifications\nthrough [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging).\nIt wraps the official `firebase-admin` SDK in a `ProviderPlugin` — the common\ninterface Emito uses to dispatch a notification to any channel — so the engine\ncan hand it a `push` payload with one or more device tokens and get back a\nnormalized `DeliveryResult`.\n\n> Provider plugins keep Emito provider-agnostic: the core engine never talks to\n> Firebase directly. It only knows the `ProviderPlugin` contract, and this\n> package translates that contract into FCM `send` calls and maps Firebase's\n> failures back into Emito's typed error model.\n\n## Install\n\n`@emito/provider-fcm` is a workspace package in the Emito monorepo and is not yet\npublished to npm. Inside the monorepo, depend on it with the workspace protocol\nand add `firebase-admin`, which is required at runtime:\n\n```jsonc\n// package.json\n{\n  \"dependencies\": {\n    \"@emito/provider-fcm\": \"workspace:*\",\n    \"firebase-admin\": \"^13.0.0\"\n  }\n}\n```\n\n`firebase-admin` is the official Firebase Admin SDK. The plugin is designed to be\nregistered with the Emito core engine alongside other channel providers.\nStandalone publishing to npm is planned.\n\n## Usage\n\n`createFcmProvider` validates its config, initializes a dedicated Firebase\nAdmin app with the supplied service-account credentials, and returns a\n`ProviderPlugin` bound to the `push` channel. Register the returned plugin with\nthe Emito engine, which calls `deliver` with each push payload.\n\n```ts\nimport { createFcmProvider } from \"@emito/provider-fcm\";\n\nconst provider = createFcmProvider({\n  projectId: process.env.FCM_PROJECT_ID!,\n  clientEmail: process.env.FCM_CLIENT_EMAIL!,\n  privateKey: process.env.FCM_PRIVATE_KEY!,\n});\n\n// The engine invokes this; shown here directly for illustration.\nconst result = await provider.deliver({\n  channel: \"push\",\n  tokens: [\"fcm-device-token-1\", \"fcm-device-token-2\"],\n  title: \"Build complete\",\n  body: \"Your deployment finished successfully.\",\n  data: { url: \"/deployments/123\" },\n  metadata: {\n    notificationId: \"ntf_123\",\n    subscriberId: \"sub_456\",\n    eventType: \"deploy.succeeded\",\n  },\n});\n\nconsole.log(result.success, result.providerMessageId, result.invalidTokens);\n```\n\nEach token is sent independently. If at least one send succeeds, `deliver`\nresolves with `{ success: true }`, a `providerMessageId` of the form\n`\"<succeeded>/<total>\"`, and an optional `invalidTokens` array listing tokens\nFirebase reported as no longer registered. If every token fails it throws an\n`EmitoError` (from `@emito/types`) with a classified code — the engine uses these\nfor retry and routing decisions. An empty `tokens` array is treated as a no-op\nsuccess.\n\n## API surface\n\n| Export | Kind | Description |\n| --- | --- | --- |\n| `createFcmProvider(config)` | function | Returns a `ProviderPlugin` for the `push` channel backed by Firebase Cloud Messaging. |\n| `FcmProviderConfigSchema` | `z.ZodObject` | Zod schema used to validate provider config. |\n| `FcmProviderConfig` | type | Inferred config type: `projectId`, `clientEmail`, and `privateKey`. |\n\n### Configuration\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `projectId` | `string` | yes | Firebase project ID from the service account. |\n| `clientEmail` | `string` | yes | Service-account client email. |\n| `privateKey` | `string` | yes | Service-account private key. |\n\n### Error mapping\n\nFirebase messaging errors are translated into `EmitoError` codes from\n`@emito/types` so the engine can act on them consistently:\n\n| Condition | Code | Retryable |\n| --- | --- | --- |\n| Unregistered / invalid registration token | `DELIVERY_INVALID_ADDRESS` | no |\n| Rate / message-rate limits | `RATE_LIMITED` | yes |\n| Server unavailable / internal / unknown error | `PROVIDER_UNAVAILABLE` | yes |\n| Invalid argument / mismatched credential, other rejections | `DELIVERY_REJECTED` | no |\n| Non-FCM / unrecognized error | `PROVIDER_UNAVAILABLE` | yes |\n| Invalid config | `CONFIG_INVALID` | — (thrown at construction) |\n\nWhen a token fails with an invalid-address code, it is collected into\n`result.invalidTokens` rather than aborting the whole batch — callers can prune\nthose tokens from their subscriber records.\n\n## Part of Emito\n\n`@emito/provider-fcm` is one package in the [Emito](../../README.md)\nmonorepo — self-hosted, provider-agnostic notification infrastructure for\nNode.js and TypeScript.\n\n- **Shared contracts** — [`@emito/types`](../types/README.md)\n- **Core engine** — [`@emito/core`](../core/README.md)\n- See the [full package list](../../README.md#monorepo) in the root README.\n\n## License\n\nMIT — part of the [Emito](../../README.md) project.\n","readmeFilename":"README.md","_rev":"1-16768a99f47e24c323f4fb81eb61063e"}