Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Firebase Authentication Laravel Package

firevel/firebase-authentication

Laravel package for integrating Firebase Authentication: verify Firebase ID tokens, use a custom auth guard, and sync Firebase users with Eloquent models. Simplifies token-based login and user management for Laravel apps.

Deep Wiki
Context7

Getting Started

Install and wire in three steps

  1. composer require firevel/firebase-authentication (it pulls in kreait/firebase-php, which does the actual JWT verification against Google's public keys).
  2. Give Laravel a service account. Drop the Firebase service-account JSON somewhere outside public/ and point the SDK at it — usually GOOGLE_APPLICATION_CREDENTIALS=/abs/path/service-account.json, or the FIREBASE_CREDENTIALS key if you publish config/firebase.php. The web user must be able to read the file.
  3. Register the guard in config/auth.php:
'guards' => [
    'firebase' => [
        'driver'   => 'firebase',
        'provider' => 'users', // your existing Eloquent provider
    ],
],

Where to look first

  • config/auth.php — the guard entry is the whole integration surface.
  • vendor/firevel/firebase-authentication/src — read the guard class first (it pulls the bearer token from the Authorization header, calls verifyIdToken, then hands the token's sub claim to the configured user provider). Everything you'll want to customize lives there or in your provider.
  • vendor/kreait/firebase-php — token verification, leeway, revocation checks, and the key cache all belong to this SDK, not to the Laravel wrapper.

First use case

A SPA or mobile app signs in with the Firebase client SDK, gets an ID token, and sends it on every request as Authorization: Bearer <idToken>. Your API routes are protected with auth:firebase; Laravel verifies the token and resolves a local User:

Route::middleware('auth:firebase')->get('/me', fn (Request $r) => $r->user());

Implementation Patterns

Map Firebase UID to a local user (the pattern you'll actually use). Add a firebase_uid column with a unique index, then implement a provider that treats the token's sub as the identifier:

class FirebaseUserProvider implements UserProvider
{
    public function retrieveById($identifier)
    {
        return User::where('firebase_uid', $identifier)->first();
    }

    public function retrieveByToken($identifier, $token) { /* not used */ }
    public function updateRememberToken(Authenticatable $user, $token) {}
    public function retrieveByCredentials(array $credentials) { return null; }
    public function validateCredentials(Authenticatable $user, array $credentials) { return false; }
}

Register it in config/auth.php under providers.users (or a new firebase provider) and the guard now resolves Eloquent models with full relationships, policies, and $user->can(...) support.

Just-in-time provisioning. If you don't want a separate signup flow, create the row inside the provider's retrieveById or in a small middleware after authentication:

User::firstOrCreate(
    ['firebase_uid' => $payload->sub],
    ['email' => $payload->email, 'name' => $payload->name ?? null]
);

Wrap this in a DB transaction and handle the unique-constraint race when two requests from the same new user land simultaneously.

Use claim data, not just the UID. The decoded token carries email, email_verified, name, picture, phone_number, and any custom claims you set via the Admin SDK. Custom claims are the cheapest way to do role checks ($payload->admin === true) without a DB round trip — but treat them as a cache, not the source of truth, since they're only refreshed when the client refreshes its token.

Guard composition. auth:firebase on a route group is enough for most APIs. If you also support session-based admin logins, keep two guards and be explicit: Route::middleware('auth:firebase') for the API, auth:web for the dashboard. For $request->user() to be correct outside middleware, call Auth::shouldUse('firebase') in a service provider or middleware.

Testing. actingAs($user, 'firebase') works for feature tests and skips token verification entirely. For tests that need the real guard path, generate tokens with firebase/php-jwt using the Firebase emulator's signing key, or bind a fake guard. Don't hit Google's key endpoint in CI.

Client side. Let the Firebase SDK own the token lifecycle: call getIdToken() before each request (it refreshes automatically when within 5 minutes of expiry) and attach the result. Never cache ID tokens in localStorage for longer than the SDK does.

Gotchas and Tips

  • Expiry is one hour. The single most common "it worked yesterday" bug is a client caching an ID token. If you see intermittent 401s, log exp from the decoded payload before blaming the server.
  • No local user, no error. A valid token whose sub doesn't match any row yields Auth::user() === null — the request passes the JWT check and dies later on a null property. Log a warning in retrieveById when lookup misses.
  • Don't auto-link by email blindly. Matching an existing local account purely on the email claim is an account-takeover vector if a provider allows unverified emails. Gate it on email_verified === true and consider requiring a manual link step for existing password users.
  • Revocation isn't checked by default. verifyIdToken validates signature and expiry; it does not confirm the user hasn't been disabled or signed out everywhere. For sensitive operations (password change, payment), pass the "check if revoked" flag through or call the Admin SDK's user lookup — otherwise a stolen token stays valid for its full hour.
  • Clock skew and leeway. Serverless hosts with drifting clocks cause spurious "token used before issued" errors. The underlying SDK exposes a leeway setting; a few seconds of tolerance fixes it without weakening verification.
  • Key-fetch latency. Verification fetches Google's public certs and caches them via PSR-16. On cold serverless starts this adds hundreds of milliseconds. Point the cache at Redis/file and warm it, or you'll see p99 spikes on the first request of each container.
  • The Authorization header disappears behind some proxies. Apache with mod_rewrite and certain nginx/FastCGI setups strip it. Check $_SERVER['HTTP_AUTHORIZATION'] before assuming the guard is broken.
  • CORS preflight. Authorization is not a simple header; your OPTIONS responses must allow it or every browser request fails before reaching the guard.
  • Provider config is easy to leave stale. If you switch from the default provider to a custom one, the guard keeps working but silently resolves different objects. Add one assertion in your test suite that auth('firebase')->user() is an App\Models\User.
  • Extend by subclassing, not forking. The guard reads the token from the standard header; if you need a cookie or a custom header (e.g. for an internal service), subclass the guard, override token extraction, and register it with Auth::extend.
  • Small package, thin maintenance. 23 stars means you'll be reading the source rather than the docs, and a major bump in kreait/firebase-php can change verification behavior underneath you. Pin the SDK version and cover the auth path with at least one integration test using a real token from the Firebase emulator.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle