diff --git a/examples/with-firebase-authentication/.env.local.example b/examples/with-firebase-authentication/.env.local.example
deleted file mode 100644
index 01054597ca44a..0000000000000
--- a/examples/with-firebase-authentication/.env.local.example
+++ /dev/null
@@ -1,13 +0,0 @@
-# Update these with your Firebase app's values.
-NEXT_PUBLIC_FIREBASE_PROJECT_ID=my-example-app-id
-NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY=MyExampleAppAPIKey123
-NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=my-example-app.firebaseapp.com
-NEXT_PUBLIC_FIREBASE_DATABASE_URL=https://my-example-app.firebaseio.com
-FIREBASE_CLIENT_EMAIL=my-example-app-email@example.com
-
-# Your Firebase private key.
-FIREBASE_PRIVATE_KEY=some-key-here
-
-# Secrets used by cookie-session.
-SESSION_SECRET_CURRENT=someSecretValue
-SESSION_SECRET_PREVIOUS=anotherSecretValue
diff --git a/examples/with-firebase-authentication/README.md b/examples/with-firebase-authentication/README.md
index 1839b5dba2085..0284550ece8d1 100644
--- a/examples/with-firebase-authentication/README.md
+++ b/examples/with-firebase-authentication/README.md
@@ -1,6 +1,6 @@
# Example: Firebase authentication with a serverless API
-This example includes Firebase authentication and serverless [API routes](https://nextjs.org/docs/api-routes/introduction). On login, the app calls `/api/login`, which stores the user's info (their decoded Firebase token) in a cookie so that it's available server-side in `getInitialProps`. On logout, the app calls `/api/logout` to destroy the cookie.
+This example includes Firebase authentication and serverless [API routes](https://nextjs.org/docs/api-routes/introduction).
## How to use
@@ -32,7 +32,6 @@ Set up Firebase:
- Get your account credentials from the Firebase console at _Project settings > Service accounts_, where you can click on _Generate new private key_ and download the credentials as a json file. It will contain keys such as `project_id`, `client_email` and `client_id`. Set them as environment variables in the `.env.local` file at the root of this project.
- Get your authentication credentials from the Firebase console under _Project settings > General> Your apps_ Add a new web app if you don't already have one. Under _Firebase SDK snippet_ choose _Config_ to get the configuration as JSON. It will include keys like `apiKey`, `authDomain` and `databaseUrl`. Set the appropriate environment variables in the `.env.local` file at the root of this project.
- Go to **Develop**, click on **Authentication** and in the **Sign-in method** tab enable authentication for the app.
-- Set the environment variables `SESSION_SECRET_CURRENT` and `SESSION_SECRET_PREVIOUS` in the `.env.local` file. (These are used by [`cookie-session`](https://github.com/expressjs/cookie-session/#secret).]
Install it and run:
diff --git a/examples/with-firebase-authentication/components/FirebaseAuth.js b/examples/with-firebase-authentication/components/FirebaseAuth.js
index 29db2152afe00..33f36786aa535 100644
--- a/examples/with-firebase-authentication/components/FirebaseAuth.js
+++ b/examples/with-firebase-authentication/components/FirebaseAuth.js
@@ -3,6 +3,7 @@ import { useEffect, useState } from 'react'
import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth'
import firebase from 'firebase/app'
import 'firebase/auth'
+import cookie from 'js-cookie'
import initFirebase from '../utils/auth/initFirebase'
// Init the Firebase app.
@@ -20,6 +21,21 @@ const firebaseAuthConfig = {
],
signInSuccessUrl: '/',
credentialHelper: 'none',
+ callbacks: {
+ signInSuccessWithAuthResult: async ({ user }, redirectUrl) => {
+ // xa is the access token, which can be retrieved through
+ // firebase.auth().currentUser.getIdToken()
+ const { uid, email, xa } = user
+ const userData = {
+ id: uid,
+ email,
+ token: xa,
+ }
+ cookie.set('auth', userData, {
+ expires: 1,
+ })
+ },
+ },
}
const FirebaseAuth = () => {
diff --git a/examples/with-firebase-authentication/package.json b/examples/with-firebase-authentication/package.json
index b504e8cf621e3..13a19a11d07cb 100644
--- a/examples/with-firebase-authentication/package.json
+++ b/examples/with-firebase-authentication/package.json
@@ -7,17 +7,15 @@
"start": "next start"
},
"dependencies": {
- "cookie-session": "1.4.0",
"firebase": "^7.6.1",
"firebase-admin": "^8.9.0",
- "lodash": "4.17.15",
+ "js-cookie": "2.2.1",
"next": "latest",
+ "next-cookies": "2.0.3",
"prop-types": "15.7.2",
"react": "^16.12.0",
"react-dom": "^16.12.0",
- "react-firebaseui": "4.0.0"
- },
- "devDependencies": {
- "dotenv": "8.2.0"
+ "react-firebaseui": "4.0.0",
+ "swr": "0.2.2"
}
}
diff --git a/examples/with-firebase-authentication/pages/_document.js b/examples/with-firebase-authentication/pages/_document.js
deleted file mode 100644
index cf504055deb89..0000000000000
--- a/examples/with-firebase-authentication/pages/_document.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* eslint react/no-danger: 0 */
-import React from 'react'
-import PropTypes from 'prop-types'
-import { get } from 'lodash/object'
-import Document, { Html, Head, Main, NextScript } from 'next/document'
-
-class CustomDocument extends Document {
- render() {
- // Store initial props from request data that we need to use again on
- // the client. See:
- // https://github.com/vercel/next.js/issues/3043#issuecomment-334521241
- // https://github.com/vercel/next.js/issues/2252#issuecomment-353992669
- // Alternatively, you could use a store, like Redux.
- const { AuthUserInfo } = this.props
- return (
-
-
-
-
-
-
-
-
-
- )
- }
-}
-
-CustomDocument.getInitialProps = async (ctx) => {
- // Get the AuthUserInfo object. This is set if the server-rendered page
- // is wrapped in the `withAuthUser` higher-order component.
- const AuthUserInfo = get(ctx, 'myCustomData.AuthUserInfo', null)
-
- const initialProps = await Document.getInitialProps(ctx)
- return { ...initialProps, AuthUserInfo }
-}
-
-CustomDocument.propTypes = {
- AuthUserInfo: PropTypes.shape({
- AuthUser: PropTypes.shape({
- id: PropTypes.string.isRequired,
- email: PropTypes.string.isRequired,
- emailVerified: PropTypes.bool.isRequired,
- }),
- token: PropTypes.string,
- }).isRequired,
-}
-
-export default CustomDocument
diff --git a/examples/with-firebase-authentication/pages/api/getFood.js b/examples/with-firebase-authentication/pages/api/getFood.js
new file mode 100644
index 0000000000000..188f4e3140f11
--- /dev/null
+++ b/examples/with-firebase-authentication/pages/api/getFood.js
@@ -0,0 +1,17 @@
+import { verifyIdToken } from '../../utils/auth/firebaseAdmin'
+const favoriteFoods = ['pizza', 'burger', 'chips', 'tortilla']
+
+const getFood = async (req, res) => {
+ const token = req.headers.token
+
+ try {
+ await verifyIdToken(token)
+ return res.status(200).json({
+ food: favoriteFoods[Math.floor(Math.random() * favoriteFoods.length)],
+ })
+ } catch (error) {
+ return res.status(401).send('You are unauthorised')
+ }
+}
+
+export default getFood
diff --git a/examples/with-firebase-authentication/pages/api/login.js b/examples/with-firebase-authentication/pages/api/login.js
deleted file mode 100644
index dad83c08f9277..0000000000000
--- a/examples/with-firebase-authentication/pages/api/login.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import commonMiddleware from '../../utils/middleware/commonMiddleware'
-import { verifyIdToken } from '../../utils/auth/firebaseAdmin'
-
-const handler = (req, res) => {
- if (!req.body) {
- return res.status(400)
- }
-
- const { token } = req.body
-
- // Here, we decode the user's Firebase token and store it in a cookie. Use
- // express-session (or similar) to store the session data server-side.
- // An alternative approach is to use Firebase's `createSessionCookie`. See:
- // https://firebase.google.com/docs/auth/admin/manage-cookies
- // Firebase docs:
- // "This is a low overhead operation. The public certificates are initially
- // queried and cached until they expire. Session cookie verification can be
- // done with the cached public certificates without any additional network
- // requests."
- // However, in a serverless environment, we shouldn't rely on caching, so
- // it's possible Firebase's `verifySessionCookie` will make frequent network
- // requests in a serverless context.
- return verifyIdToken(token)
- .then((decodedToken) => {
- req.session.decodedToken = decodedToken
- req.session.token = token
- return decodedToken
- })
- .then((decodedToken) => {
- return res.status(200).json({ status: true, decodedToken })
- })
- .catch((error) => {
- return res.status(500).json({ error })
- })
-}
-
-export default commonMiddleware(handler)
diff --git a/examples/with-firebase-authentication/pages/api/logout.js b/examples/with-firebase-authentication/pages/api/logout.js
deleted file mode 100644
index f6c761f7eb267..0000000000000
--- a/examples/with-firebase-authentication/pages/api/logout.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import commonMiddleware from '../../utils/middleware/commonMiddleware'
-
-const handler = (req, res) => {
- // Destroy the session.
- // https://github.com/expressjs/cookie-session#destroying-a-session
- req.session = null
- res.status(200).json({ status: true })
-}
-
-export default commonMiddleware(handler)
diff --git a/examples/with-firebase-authentication/pages/auth.js b/examples/with-firebase-authentication/pages/auth.js
index 65e593960e19b..431eaf691e108 100644
--- a/examples/with-firebase-authentication/pages/auth.js
+++ b/examples/with-firebase-authentication/pages/auth.js
@@ -11,6 +11,4 @@ const Auth = () => {
)
}
-Auth.propTypes = {}
-
export default Auth
diff --git a/examples/with-firebase-authentication/pages/example.js b/examples/with-firebase-authentication/pages/example.js
index c2697f7afe556..6f179479fd365 100644
--- a/examples/with-firebase-authentication/pages/example.js
+++ b/examples/with-firebase-authentication/pages/example.js
@@ -14,10 +14,4 @@ const Example = (props) => {
)
}
-Example.displayName = 'Example'
-
-Example.propTypes = {}
-
-Example.defaultProps = {}
-
export default Example
diff --git a/examples/with-firebase-authentication/pages/index.js b/examples/with-firebase-authentication/pages/index.js
index 3c2a2619125f6..303032df49520 100644
--- a/examples/with-firebase-authentication/pages/index.js
+++ b/examples/with-firebase-authentication/pages/index.js
@@ -1,113 +1,60 @@
-import PropTypes from 'prop-types'
-import { get } from 'lodash/object'
+import useSWR from 'swr'
import Link from 'next/link'
-import Router from 'next/router'
-import withAuthUser from '../utils/pageWrappers/withAuthUser'
-import withAuthUserInfo from '../utils/pageWrappers/withAuthUserInfo'
-import logout from '../utils/auth/logout'
-
-const Index = (props) => {
- const { AuthUserInfo, data } = props
- const AuthUser = get(AuthUserInfo, 'AuthUser', null)
- const { favoriteFood } = data
+import { useUser } from '../utils/auth/useUser'
+
+const fetcher = (url, token) =>
+ fetch(url, {
+ method: 'GET',
+ headers: new Headers({ 'Content-Type': 'application/json', token }),
+ credentials: 'same-origin',
+ }).then((res) => res.json())
+
+const Index = () => {
+ const { user, logout } = useUser()
+ const { data, error } = useSWR(
+ user ? ['/api/getFood', user.token] : null,
+ fetcher
+ )
- return (
-