Sign in¶
Now let's implement a sign in page.
fireauth
├── .env.development
├── .firebaserc
├── .git
│   └── ...
├── .gitignore
├── .vscode
│   ├── settings.json
│   └── tasks.json
├── README.md
├── firebase-debug.log
├── firebase.json
├── firestore-debug.log
├── firestore.indexes.json
├── firestore.rules
├── functions
│   ├── .gitignore
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
├── jsconfig.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── src
│   ├── app
│   │   ├── Home.jsx
│   │   ├── layout.js
│   │   ├── page.js
│   │   ├── signin
│   │   │   ├── SignInForm.js
│   │   │   └── page.js
│   │   └── signup
│   │       ├── SignUpForm.js
│   │       └── page.js
│   └── firebase
│       └── firebase.js
└── ui-debug.log
        import { SignInForm } from "./SignInForm"
 
export default function SignupPage() {
  return (
    <>
      <div>Sign in page</div>
      <SignInForm />
    </>
  )
}
        "use client"
 
import { auth } from "@/firebase/firebase"
import { signInWithEmailAndPassword } from "firebase/auth"
import { useRouter } from "next/navigation"
import { useState } from "react"
 
export function SignInForm() {
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")
  const router = useRouter()
 
  const handleFormSubmit = (event) => {
    event.preventDefault()
 
    signInWithEmailAndPassword(auth, email, password)
      .then((userCredential) => {
        router.push("/")
      })
      .catch((error) => {
        console.log("Error:", error)
      })
  }
 
  return (
    <form onSubmit={handleFormSubmit}>
      <label>Email:</label>
      <input
        type="text"
        value={email}
        onChange={(event) => setEmail(event.target.value)}
      />
 
      <label>Password:</label>
      <input
        type="password"
        value={password}
        onChange={(event) => setPassword(event.target.value)}
      />
 
      <button type="submit">Sign in</button>
    </form>
  )
}
        The sign in code and functionality is very similar to the sign up functionality. In short, when a user signs in
- The 
signInWithEmailAndPassword()function is invoked. - A pair of 
POSTrequests are made toidentitytoolkit.googleapis.com.- The first 
POSTrequest hits theaccounts:signInWithPasswordendpoint. If the response is good (200), it returns the user'sidTokenas a JWT. - The second 
POSTrequest hits theaccounts:lookupendpoint. 
 - The first 
 router.push("/")redirects the user to the home page.
Sign out¶
Now let's implement the Sign out button.
"use client"
 
import { auth } from "@/firebase/firebase"
import { onAuthStateChanged, signOut } from "firebase/auth"
import Link from "next/link"
import { useEffect, useState } from "react"
 
export function Home() {
  const [authUser, setAuthUser] = useState(undefined)
 
  useEffect(() => {
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setAuthUser(user)
    })
    return unsubscribe
  }, [])
 
  const handleSignOut = () => {
    signOut(auth)
  }
 
  return (
    authUser === undefined
      ? <div>Loading...</div>
      : (
        authUser
          ? <button onClick={ handleSignOut }>Sign out</button>
          : <>
            <Link href="/signup">Sign up</Link>
            <span> | </span>
            <Link href="/signin">Sign in</Link>
          </>
      )
  )
}
  Let's see it in action, paying close attention to the IndexedDB.
Notice the sign out mechanism deletes the user data from the IndexedDB.