npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geckou/firebase-server

v0.4.0

Published

Server-side Firebase helpers (Auth middleware / FCM push) for Cloud Functions and other Node servers

Readme

@geckou/firebase-server

サーバーサイド(Cloud Functions 等)向けの Firebase ヘルパー。 Firebase Auth の ID トークンを検証する Express 互換ミドルウェアと、FCM によるプッシュ通知送信を提供する。

firebase-admin / express は依存に持たない。インスタンスは利用側から注入し、 型は使用するメソッドだけを構造的に要求する(TokenVerifierLike / MessagingLike)。 peer の型を公開 API に使うとメジャーバージョン間の型定義の差が利用側の型エラーになるため (@geckou/billing の StripeClientLike と同じ扱い)。getAuth() / getMessaging() の 戻り値はそのまま渡せる。

インストール

yarn add @geckou/firebase-server

firebase-admin は利用側のプロジェクトが持っている前提(Cloud Functions なら必ずある)。

認証ミドルウェア

import { createRequireAuth } from '@geckou/firebase-server'
import { getAuth } from 'firebase-admin/auth'

// ゲッターで渡すと Auth の解決がリクエスト時まで遅延されるため、
// initializeApp() より先にミドルウェアを定義しても安全
export const requireAuth = createRequireAuth(getAuth)

// 失効(revokeRefreshTokens)済みのトークンも弾きたい場合。
// 検証のたびに Firebase Auth へ問い合わせるので、レイテンシと呼び出し回数が増える。
// 既定(false)だと、失効させても ID トークンの有効期限(最大 1 時間)は通り続ける
export const requireFreshAuth = createRequireAuth(getAuth, {
  checkRevoked: true,
})
import type { AuthenticatedRequest } from '@geckou/firebase-server'
import type { Request } from 'express'

app.get('/me', requireAuth, (req, res) => {
  // 検証に成功すると req.uid に uid、req.token に検証済みトークン全体が入る
  const { uid, token } = req as Request & AuthenticatedRequest
  res.json({ uid, plan: token.plan })
})

req.token は verifyIdToken の戻り値そのもの。@geckou/billing の syncClaims が書く subscriptionActive / plan や role などのカスタムクレームは全てここに載るので、 ハンドラ側で再度 verifyIdToken を呼んだり Firestore を読んだりする必要はない。 型は { uid: string } & Record<string, unknown>(DecodedTokenLike)なので、 uid 以外は利用側で絞り込むこと。

TokenVerifierLike が要求する戻り値は { uid: string } のまま(最小契約)。 DecodedTokenLike を要求すると、uid を持つ interface / class を返す独自 verifier が インデックスシグネチャ不足で代入できなくなるため。

Authorization: Bearer <ID トークン> を検証し、トークンが無い・不正な場合は 401 { "error": "Unauthorized" } を返してハンドラへ進まない。

⚠️ next() は try の外で呼ぶ実装になっている(中で呼ぶと後続ハンドラの 同期例外まで 401 に化けるため)。その代わり、後続ハンドラが投げた例外は このミドルウェアの Promise の reject として外へ出る。Express 4 は async ミドルウェアの reject を捕まえないので、express-async-errors を読み込むか Express 5 を使うこと。捕まえないままだと unhandledRejection になり、 クライアントへレスポンスが返らない。

import 'express-async-errors' // Express 4 のみ必要

プッシュ通知(FCM)

import {
  sendPushNotification,
  sendPushNotificationBatch,
} from '@geckou/firebase-server'
import { getMessaging } from 'firebase-admin/messaging'

// 単一デバイス
await sendPushNotification(getMessaging(), fcmToken, {
  title: '新着メッセージ',
  body: '○○さんからメッセージが届きました',
  data: { screen: 'chat' },
})

// 複数デバイス(トークンが空配列なら送信せず 0 件で返る)
const { successCount, failureCount, invalidTokens, errors } =
  await sendPushNotificationBatch(getMessaging(), fcmTokens, {
    title: 'お知らせ',
    body: '本文',
  })

// アンインストール済み端末などのトークンは恒久的に失敗する。
// 保存先から消さないと溜まり続け、送信のたびに失敗数が増える
await removeFcmTokens(invalidTokens)

FCM は 1 リクエストにつき 500 件までのため、sendPushNotificationBatch は 500 件ずつに分割して送り、件数を合算して返す(呼び出し側で分ける必要はない)。

分割したチャンクの送信そのものが失敗しても throw せず、そのチャンクの件数を failureCount に計上し、{ error, tokens } を errors に入れて返す。途中で throw すると、 それ以前のチャンクで判明した invalidTokens を呼び出し側が掃除できず、 次回も同じ失敗を繰り返すため。再試行するときは errors[].tokens だけを送り直す (全件を送り直すと、成功済みのトークンに通知が二重に届く)。

モバイル側の受信(権限リクエスト・トークン取得)はこのパッケージの対象外。 テンプレートの apps/mobile/src/lib/push-notifications.ts(expo-notifications)が担当する。