Day 8: Authentication

Thursday, May 25, 2017

Lecture Videos

Morning:

Afternoon:

Topics

Firebase Authentication

  • ‘firebase/auth’
  • authWithPopup
  • signing in and out
  • handling auth state changes

Examples

Firebase Authentication

Firebase isn’t just a real-time database. It can also provide authentication services via email/password, phone, or common third-party services like Github, Facebook, and Google. For ThingList, we set up authentication via Github OAuth.

Step 1: Get your authorization callback URL from Firebase

Navigate to your project in Firebase console. Click on the ‘Authenticate’ tab on the left and then on the Github logo. Copy the authorization callback URL.

The data for the Client ID and Client Secret will be generated in the next step.

Step 2: Register your app in Github

Log in to Github and click on ‘Settings’. On the left hand side, click on ‘OAuth Applications’ under the ‘Developer settings’ menu. Register a new app and fill out the form.

Use the Authorization callback URL from step 1

After successfully registering the app, you’ll be taken to your new app’s settings page.

Seeeeecrets... (Don't worry, this app has been deleted. Never post your app secrets publicly.)

Step 3: Enable Github authentication in Firebase

Go back to the Github authentication tab in Firebase and fill in the Client ID and Client Secret that you got from registering your app with Github.

More Seeeeecrets... (But seriously, don't share your secrets)

Step 4: Add Firebase auth to your app

Note: This step assumes you already have your Firebase database added to your app.

Import firebase/auth into your app’s firebase setup. Enable firebase auth and also create an instance of GithubAuthProvider.

base.js


  
import Rebase from 're-base'
import firebase from 'firebase/app'
import database from 'firebase/database'
import 'firebase/auth'

const app = firebase.initializeApp({
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: ""
})

const db = database(app)

export const auth = app.auth()
export const githubProvider = new firebase.auth.GithubAuthProvider()

export default Rebase.createClass(db)

  
  

Step 5: Set up the SignIn Component

Import auth and the githubProvider into whatever component handles the sign-in process. Call signInWithPopup on the auth object, passing the provider as a parameter. Then call an authHandler function when the promise resolves to handle whatever you want to do after authorization is successful.

SignIn.js



import React from 'react'
import { auth, githubProvider } from './base'

const SignIn = ({ authHandler }) => {
  const authenticate = (provider) => {
    auth
      .signInWithPopup(provider)
      .then(authHandler)
  }

  return (
    <button className="SignIn" onClick={() => authenticate(githubProvider)}>
      Sign In With GitHub
    </button>
  )
}

export default SignIn


Step 6: Finishing sign-in

What the authHandler callback does is up to you, but for ThingList, we had it do pretty typical things - save the user ID to state, and initialize syncing our local state for ‘things’ with the data stored on Firebase.

App.js



// ...

authHandler = (authData) => {
  this.setState(
    { uid: authData.user.uid },
    this.syncThings
  )
}

// ...


Step 7: Handling auth state changes (and page refreshes)

What happens if auth state changes? Or the user refreshes the page? We should probably set up something to listen for that. In the componentWillMount lifecycle hook that runs when the Component is first getting loaded, we can call the onAuthStateChanged method to set up such a listener.

App.js



// ...

componentWillMount() {
  auth.onAuthStateChanged(
    (user) => {
      if (user) {
        this.authHandler({ user })
      }
    }
  )
}

// ...


Step 8: Signing out

Signing out when using Firebase for authentication is quite simple - just call auth.signOut()! Once the promise returned by signOut has resolved, you can handle any additional cleanup. In ThingList, we just set state.uid back to null.

App.js



// ...

signOut = () => {
  auth
    .signOut()
    .then(() => this.setState({ uid: null }))
}

// ...


Projects

Homework

PRACTICE! Extend a project from class. Write a new project. Add a different type of authentication. You know enough to start building things on your own, and it’s definitely the best way to learn once you have the basics down.