Table of Contents
- Set up Firebase
- Set up the front end
- Add context
- Add Private route
- Add Routing
- Create `Home`, `Login` and `Signup` components.
- src/auth/Signup.jsx
- References
Set up Firebase
Create a new app
First go to firebase console and create new app.
Add auth
Click Authentication and then click SET UP SIGN-IN METHOD
.
And enable things you want to use to sign in.
Get firebase credentials
Go to your project settings and get the app’s firebase credentials.
The credentials look something like below
apiKey: "your_key",
authDomain: "your_app_id.firebaseapp.com",
databaseURL: "https://your_app_id.firebaseio.com",
projectId: "your_app_id",
storageBucket: "your_storage_bucket",
messagingSenderId: "sender_id",
appId: "your_app_id"
Set up the front end
Create your app.
$ create-react-app your-app-name
$ cd your-app-name
Install react-router
and firebase
packages.
$ yarn add firebase react-router react-router-dom
Connect the App to firebase
Paste your firebase credentials to .env
.
// .env
REACT_APP_FIREBASE_KEY="your_key"
REACT_APP_FIREBASE_DOMAIN="your_app_id.firebaseapp.com"
REACT_APP_FIREBASE_DATABASE="https://your_app_id.firebaseio.com"
REACT_APP_FIREBASE_PROJECT_ID="your_app_id"
REACT_APP_FIREBASE_STORAGE_BUCKET="your_storage_bucket"
REACT_APP_FIREBASE_SENDER_ID="sender_id"
Create a new file src/base.js
. And paste the code below.
It initiates your firebase application with the given credentials.
import * as firebase from 'firebase/app'
import 'firebase/auth'
export const app = firebase.initializeApp({
apiKey: process.env.REACT_APP_FIREBASE_KEY,
authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID,
})
Add context
Create src/auth/AuthProvider
and put all the authentication logic in here.
And we are going to pass the authentication data and functions through the component tree using Context
.
import React, { useEffect, useState } from 'react'
import { app } from '../base.js'
export const AuthContext = React.createContext()
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null)
const login = async (email, password, history) => {
try {
await app.auth().signInWithEmailAndPassword(email, password)
history.push('/')
} catch (error) {
alert(error)
}
}
const signup = async (email, password, history) => {
try {
await app.auth().createUserWithEmailAndPassword(email, password)
history.push('/')
} catch (error) {
alert(error)
}
}
useEffect(() => {
app.auth().onAuthStateChanged(setCurrentUser)
}, [])
return (
<AuthContext.Provider
value={{
login: login,
signup: signup,
currentUser,
}}
>
{children}
</AuthContext.Provider>
)
}
Add Private route
Create src/auth/PrivateRoute
and paste the code below.
The idea is that only authenticated users can access the private route.
import React, { useContext } from 'react'
import { Route } from 'react-router-dom'
import { AuthContext } from './AuthProvider'
import Login from './Login'
const PrivateRoute = ({ component: RouteComponent, ...options }) => {
const { currentUser } = useContext(AuthContext)
const Component = currentUser ? RouteComponent : Login
return <Route {...options} component={Component} />
}
export default PrivateRoute
Add Routing
Open src/App.js
paste the code below.
import React from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import PrivateRoute from './auth/PrivateRoute'
import { AuthProvider } from './auth/AuthProvider'
import Home from './components/Home'
import Login from './auth/Login'
import SignUp from './auth/SignUp'
const App = () => {
return (
<AuthProvider>
<Router>
<div>
<PrivateRoute exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/signup" component={SignUp} />
</div>
</Router>
</AuthProvider>
)
}
export default App
Create Home
, Login
and Signup
components.
Create the following compoentns.
src/components/Home.jsx
import React from 'react'
import { app } from '../base'
function Home(props) {
return (
<div>
<h2>Home Page</h2>
<button onClick={() => app.auth().signOut()}>Sign out</button>
</div>
)
}
export default Home
src/auth/Login.jsx
import React, { useContext } from 'react'
import { withRouter } from 'react-router'
import { AuthContext } from './AuthProvider'
const Login = ({ history }) => {
const { login } = useContext(AuthContext)
const handleSubmit = event => {
event.preventDefault()
const { email, password } = event.target.elements
login(email.value, password.value, history)
}
return (
<div>
<h1>Log in</h1>
<form onSubmit={handleSubmit}>
<label>
Email
<input name="email" type="email" placeholder="Email" />
</label>
<label>
Password
<input name="password" type="password" placeholder="Password" />
</label>
<button type="submit">Log in</button>
</form>
</div>
)
}
export default withRouter(Login)
src/auth/Signup.jsx
import React, { useContext } from 'react'
import { withRouter } from 'react-router'
import { AuthContext } from './AuthProvider'
const SignUp = ({ history }) => {
const { signup } = useContext(AuthContext)
const handleSubmit = event => {
event.preventDefault()
const { email, password } = event.target.elements
signup(email.value, password.value, history)
}
return (
<div>
<h1>Sign up</h1>
<form onSubmit={handleSubmit}>
<label>
Email
<input name="email" type="email" placeholder="Email" />
</label>
<label>
Password
<input name="password" type="password" placeholder="Password" />
</label>
<button type="submit">Sign Up</button>
</form>
</div>
)
}
export default withRouter(SignUp)