Skip to content
Docs
Getting started
Sign in with Server Action

Sign in with Server Action

You can follow the official firebase/auth guide (opens in a new tab) to handle operations like signInWithEmailAndPassword or signOut.

refreshCookiesWithIdToken

The refreshCookiesWithIdToken method updates browser cookies with the latest authenticated credentials based on the idToken. This method works with Server Actions and Middleware. After performing Firebase operations in a Server Action, you can use this method to refresh the browser cookies with updated credentials.

Example loginAction and LoginPage

Note for Vercel users: The firebase/auth library isn't fully compatible with Vercel environments when used inside Server Actions.

If you get a ReferenceError: document is not defined, move the firebase/auth import to a client component.

Below is a simple example of a login page client component that lets users sign in using a Server Action and the refreshCookiesWithIdToken method.

First, let’s define our Server Action:

login.tsx
'use server';
 
import {refreshCookiesWithIdToken} from 'next-firebase-auth-edge/lib/next/cookies';
import {signInWithEmailAndPassword} from 'firebase/auth';
import {cookies, headers} from 'next/headers';
import {redirect} from 'next/navigation';
 
// See starter example for implementation: https://github.com/awinogrodzki/next-firebase-auth-edge/tree/main/examples/next-typescript-starter
import {getFirebaseAuth} from '@/app/auth/firebase';
import {authConfig} from '@/config/server-config';
 
export async function loginAction(username: string, password: string) {
  const credential = await signInWithEmailAndPassword(
    getFirebaseAuth(),
    username,
    password
  );
 
  const idToken = await credential.user.getIdToken();
 
  await refreshCookiesWithIdToken(idToken, headers(), cookies(), authConfig);
  redirect('/');
}

Next, create LoginPage client component that will call login action:

LoginPage.tsx
'use client';
 
import * as React from 'react';
 
interface LoginPageProps {
  loginAction: (email: string, password: string) => void;
}
 
export default function LoginPage({loginAction}: LoginPageProps) {
  const [email, setEmail] = React.useState('');
  const [password, setPassword] = React.useState('');
  let [isLoginActionPending, startTransition] = React.useTransition();
 
  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault();
    event.stopPropagation();
 
    startTransition(() => loginAction(email, password));
  }
 
  return (
    <div>
      <h1>Login</h1>
      <form onSubmit={handleSubmit}>
        <input
          required
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          name="email"
          type="email"
          placeholder="Email address"
        />
        <br />
        <input
          required
          name="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          type="password"
          placeholder="Password"
          minLength={8}
        />
        <button disabled={isLoginActionPending} type="submit">
          Submit
        </button>
      </form>
    </div>
  );
}

Lastly, let's use LoginPage inside page.tsx Server Component:

page.tsx
import LoginPage from './LoginPage';
import {loginAction} from './login';
 
export default function Page() {
  return <LoginPage loginAction={loginAction} />;
}