├── app ├── favicon.ico ├── components │ ├── spinner.gif │ ├── Spinner.jsx │ └── Navbar.jsx ├── about │ └── page.jsx ├── page.js ├── globals.css ├── layout.js ├── firebase.js ├── profile │ └── page.jsx └── context │ └── AuthContext.js ├── jsconfig.json ├── next.config.js ├── postcss.config.js ├── package.json ├── .gitignore ├── tailwind.config.js ├── public ├── vercel.svg └── next.svg └── README.md /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireclint/next-auth-firebase/HEAD/app/favicon.ico -------------------------------------------------------------------------------- /app/components/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fireclint/next-auth-firebase/HEAD/app/components/spinner.gif -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /app/about/page.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const page = () => { 4 | return ( 5 |
About Page
6 | ) 7 | } 8 | 9 | export default page -------------------------------------------------------------------------------- /app/page.js: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | 3 | export default function Home() { 4 | return ( 5 |
6 |

Home Page

7 |
8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /app/components/Spinner.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Image from "next/image"; 3 | import loader from "./spinner.gif"; 4 | 5 | const Spinner = () => { 6 | return ( 7 |
8 | loading.. 9 |
10 | ); 11 | }; 12 | 13 | export default Spinner; 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "next-auth-firebase", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "autoprefixer": "10.4.14", 13 | "encoding": "^0.1.13", 14 | "firebase": "^9.23.0", 15 | "next": "13.4.7", 16 | "postcss": "8.4.24", 17 | "react": "18.2.0", 18 | "react-dom": "18.2.0", 19 | "tailwindcss": "3.3.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './app/**/*.{js,ts,jsx,tsx,mdx}', 7 | ], 8 | theme: { 9 | extend: { 10 | backgroundImage: { 11 | 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 12 | 'gradient-conic': 13 | 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', 14 | }, 15 | }, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /app/layout.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import Navbar from "./components/Navbar"; 3 | import "./globals.css"; 4 | import { Inter } from "next/font/google"; 5 | import { AuthContextProvider } from "./context/AuthContext"; 6 | 7 | const inter = Inter({ subsets: ["latin"] }); 8 | 9 | export const metadata = { 10 | title: "Create Next App", 11 | description: "Generated by create next app", 12 | }; 13 | 14 | export default function RootLayout({ children }) { 15 | return ( 16 | 17 | 18 | 19 | 20 | {children} 21 | 22 | 23 | 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /app/firebase.js: -------------------------------------------------------------------------------- 1 | // Import the functions you need from the SDKs you need 2 | import { initializeApp } from "firebase/app"; 3 | // TODO: Add SDKs for Firebase products that you want to use 4 | // https://firebase.google.com/docs/web/setup#available-libraries 5 | import { getAuth } from "firebase/auth"; 6 | 7 | // Your web app's Firebase configuration 8 | const firebaseConfig = { 9 | apiKey: "YOUR_API_KEY", 10 | authDomain: "YOUR_AUTH_DOMAIN", 11 | projectId: "YOUR_PROJECT_ID", 12 | storageBucket: "YOUR_STORAE_BUCKET", 13 | messagingSenderId: "YOUR_MESSAGING_SENDER_ID", 14 | appId: "YOUR_APP_ID", 15 | }; 16 | 17 | // Initialize Firebase 18 | const app = initializeApp(firebaseConfig); 19 | export const auth = getAuth(app); 20 | -------------------------------------------------------------------------------- /app/profile/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import React, { useEffect, useState } from "react"; 3 | import { UserAuth } from "../context/AuthContext"; 4 | import Spinner from "../components/Spinner"; 5 | 6 | const page = () => { 7 | const { user } = UserAuth(); 8 | const [loading, setLoading] = useState(true); 9 | 10 | useEffect(() => { 11 | const checkAuthentication = async () => { 12 | await new Promise((resolve) => setTimeout(resolve, 50)); 13 | setLoading(false); 14 | }; 15 | checkAuthentication(); 16 | }, [user]); 17 | 18 | return ( 19 |
20 | {loading ? ( 21 | 22 | ) : user ? ( 23 |

24 | Welcome, {user.displayName} - you are logged in to the profile page - 25 | a protected route. 26 |

27 | ) : ( 28 |

You must be logged in to view this page - protected route.

29 | )} 30 |
31 | ); 32 | }; 33 | 34 | export default page; 35 | -------------------------------------------------------------------------------- /app/context/AuthContext.js: -------------------------------------------------------------------------------- 1 | import { useContext, createContext, useState, useEffect } from "react"; 2 | import { 3 | signInWithPopup, 4 | signOut, 5 | onAuthStateChanged, 6 | GoogleAuthProvider, 7 | } from "firebase/auth"; 8 | import { auth } from "../firebase"; 9 | 10 | const AuthContext = createContext(); 11 | 12 | export const AuthContextProvider = ({ children }) => { 13 | const [user, setUser] = useState(null); 14 | 15 | const googleSignIn = () => { 16 | const provider = new GoogleAuthProvider(); 17 | signInWithPopup(auth, provider); 18 | }; 19 | 20 | const logOut = () => { 21 | signOut(auth); 22 | }; 23 | 24 | useEffect(() => { 25 | const unsubscribe = onAuthStateChanged(auth, (currentUser) => { 26 | setUser(currentUser); 27 | }); 28 | return () => unsubscribe(); 29 | }, [user]); 30 | 31 | return ( 32 | 33 | {children} 34 | 35 | ); 36 | }; 37 | 38 | export const UserAuth = () => { 39 | return useContext(AuthContext); 40 | }; 41 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | # or 12 | pnpm dev 13 | ``` 14 | 15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 16 | 17 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. 18 | 19 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /app/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import Link from "next/link"; 3 | import { UserAuth } from "../context/AuthContext"; 4 | 5 | const Navbar = () => { 6 | const { user, googleSignIn, logOut } = UserAuth(); 7 | const [loading, setLoading] = useState(true); 8 | 9 | const handleSignIn = async () => { 10 | try { 11 | await googleSignIn(); 12 | } catch (error) { 13 | console.log(error); 14 | } 15 | }; 16 | 17 | const handleSignOut = async () => { 18 | try { 19 | await logOut(); 20 | } catch (error) { 21 | console.log(error); 22 | } 23 | }; 24 | 25 | useEffect(() => { 26 | const checkAuthentication = async () => { 27 | await new Promise((resolve) => setTimeout(resolve, 50)); 28 | setLoading(false); 29 | }; 30 | checkAuthentication(); 31 | }, [user]); 32 | 33 | return ( 34 |
35 | 49 | 50 | {loading ? null : !user ? ( 51 | 59 | ) : ( 60 |
61 |

Welcome, {user.displayName}

62 |

63 | Sign out 64 |

65 |
66 | )} 67 |
68 | ); 69 | }; 70 | 71 | export default Navbar; 72 | --------------------------------------------------------------------------------