This reusable Next.js with Firebase checklist helps you separate browser and server responsibilities, configure authentication and Firestore safely, choose an SSR strategy, and deploy without exposing credentials or creating avoidable maintenance work.
Overview
A reliable Next.js Firebase integration starts with one architectural decision: the Firebase client SDK and the Firebase Admin SDK do different jobs and must not be treated as interchangeable.
- Client SDK: Runs in the browser or a client-rendered component. Use it for Firebase Authentication, interactive Firestore access, and other features protected by Firebase Security Rules.
- Admin SDK: Runs only in trusted server code. Use it in route handlers, server actions, background jobs, or other server-side modules that need privileged access.
- Next.js application code: Decides where rendering, authentication checks, data fetching, caching, and redirects occur.
For a maintainable setup, keep these boundaries visible in the project structure. A browser Firebase module should never import the Admin SDK, and a server module should not depend on browser-only objects such as window or localStorage. This separation is useful during upgrades because changes in Next.js rendering or runtime behavior are less likely to affect every Firebase integration point at once.
Use the modular Firebase Web SDK in client code, keep configuration values in environment variables, and initialize the Admin SDK once per server process. Firebase Web configuration values are intended to identify a project; Admin credentials are different and must remain private.
Checklist by scenario
Starting a new application
- Create or select the Firebase project and register the web app.
- Enable only the Firebase products required for the first feature.
- Install the Firebase client package and create a small module such as
lib/firebase/client.ts. - Store browser configuration in the environment variables expected by the application. Do not commit local environment files containing secrets.
- Initialize the Admin SDK in a separate server-only module, such as
lib/firebase/admin.ts. - Define Firestore collections, indexes, and access rules before building many screens. Document which reads happen in the browser and which require trusted server logic.
- Start the Emulator Suite early so authentication, Firestore, and rules can be tested without changing production data.
Adding Firebase Authentication
- Choose the providers your application actually needs and configure their redirect or domain requirements.
- Use the client SDK for sign-in and sign-out interactions.
- Decide how the server will recognize an authenticated user. Common patterns include sending an ID token to a server endpoint for verification or exchanging it for a server-managed session cookie.
- Verify credentials on the server before performing privileged work. Never treat a user ID supplied in an unverified request as proof of identity.
- For protected pages, determine whether the check belongs in a server component, route handler, or middleware. Keep authorization decisions close to the data or action they protect.
- Test expired tokens, signed-out users, provider errors, account linking, and users who lack required roles or claims.
For a broader identity design checklist, see the Firebase Authentication Architecture Guide.
Reading and writing Firestore data
- Use the client SDK when the operation should be governed by Firestore Security Rules and can safely occur from the browser.
- Use the Admin SDK when a trusted server operation must bypass client rules, but add explicit authorization checks first.
- Model queries around the screens and workflows that will use them. Avoid retrieving an entire collection when a bounded, indexed query is sufficient.
- Define loading, empty, error, and permission-denied states rather than assuming every request succeeds.
- Choose caching deliberately. A cached response can be useful for public or slowly changing data, but user-specific or permission-sensitive data requires careful cache boundaries.
The Firestore Data Modeling Guide provides a useful companion checklist for collections, subcollections, indexes, and query patterns.
Deploying the application
- Choose a deployment target that supports the Next.js features your application uses, including server rendering, route handlers, and server actions.
- Configure separate Firebase project aliases or environment sets for development, staging, and production.
- Provide server credentials through the deployment platform's secret or environment-variable system. Do not place a service-account key in client-exposed variables.
- Test the production build locally or in a preview environment before changing the live project.
- Deploy Firebase rules, indexes, functions, and hosting configuration through a repeatable CI/CD process rather than relying on undocumented manual steps.
What to double-check
| Concern | Client-side approach | Server-side approach |
|---|---|---|
| Firebase initialization | Firebase Web SDK with public project configuration | Admin SDK initialized once with private credentials |
| Authentication | Sign-in state and interactive provider flows | Verify ID tokens or session cookies before protected work |
| Firestore access | Queries controlled by Firebase Security Rules | Admin queries with application-level authorization |
| Rendering | Client components for interactive state | Server components or route handlers for server data and redirects |
| Secrets | Never expose private keys or service-account material | Use deployment-managed secrets and restrict access |
| Caching | Manage local state and request refreshes | Set cache behavior according to data sensitivity and freshness |
Review runtime compatibility before placing Admin SDK code in middleware or edge-oriented paths. Middleware may run under constraints that differ from a standard Node.js server runtime. If a dependency requires Node-specific behavior, move the operation to a compatible route handler or server action and let middleware perform only a lightweight, compatible check.
Also double-check that environment-variable names match the deployment configuration, that the Firebase project selected by the CLI is the intended one, and that local emulators are not accidentally referenced by a production build.
Common mistakes
- Importing Admin code into client code: Keep server modules behind clear boundaries and use server-only conventions supported by your project setup.
- Relying on hidden UI controls for authorization: Hiding a button is not an access-control mechanism. Enforce permissions in Security Rules or trusted server code.
- Assuming SSR automatically knows the Firebase user: Server rendering needs a deliberate token or session transfer strategy.
- Using Admin access for every read: This can bypass the protections and query behavior you intended for browser access. Use the least-privileged path that fits the feature.
- Creating a new Admin app repeatedly: Centralize initialization and handle hot reload or repeated server imports without creating unnecessary app instances.
- Skipping rules tests: Test allowed and denied reads and writes with representative authenticated, unauthenticated, and role-based users. Use the Firebase Security Rules Testing Guide as a workflow reference.
- Deploying without cost and observability checks: Review reads, writes, function invocations, logs, and error rates before and after a release. The Firebase Cost Optimization Guide covers the operational review.
When to revisit
Revisit this checklist before seasonal planning cycles, after upgrading Next.js or the Firebase SDK, and whenever the application adds protected routes, server actions, new authentication providers, or a new deployment target. Changes to rendering defaults, runtime support, authentication flows, or environment-variable handling can alter a previously safe integration pattern.
Use this practical review sequence:
- Read the relevant Next.js and Firebase release notes for the versions your project uses.
- Run the application and its rules tests against the Emulator Suite.
- Inspect the production build for accidental client exposure of server modules or credentials.
- Exercise sign-in, sign-out, expired sessions, denied access, Firestore failures, and cache behavior.
- Deploy to a preview or staging project, verify logs and costs, then promote through the documented CI/CD workflow.
Keep the client/server reference table and environment-variable inventory beside the repository. That small piece of documentation makes future upgrades, team handoffs, and incident reviews substantially easier.