1.0.1 • Published 6 years ago

redux-firebase-user v1.0.1

Weekly downloads
4
License
ISC
Repository
github
Last release
6 years ago

redux-firebase-user

This is a truely modular redux module, which handles authentication with firebase and react. The goal of this module is to make authentication with firebase trivial. You can set up a whole signup process within minutes without worrying about state.

This Module exports the following

  • RenderProps: RenderProps inject behaviour within a local scope
  • HOCs: Higher ordered components, which inject behaviour in the wrapped React-Components
  • Components: Normal React-Components which interact with the reducer state
  • Selectors: Selectors for requesting the reducer state
  • ActionTypes: All the action types, the reducer uses
  • Actions: Dispatchable actions are used to modify the reducer state
  • Configuration Singleton: A singleton in order to customize the module

Install

$ npm i -S redux-firebase-user

Table of Contents

Setup

// index,js
import userModule from 'redux-firebase-user'
import firebase from 'firebase'
import * as firebaseRef from 'firebase/app'

firebase.initializeApp(/* YOUR CONFIG */)

userModule.initializeModule({
  firebase: firebaseRef // NOT firebase! only 'firebase/app' holds methods for AuthO login
})

// reducer.js
import { createStore, combineReducers } from 'redux'
import { reducer as userReducer } from 'redux-firebase-user'

const reducers = {
  // ... your other reducers here ...
  user: userReducer
}
const reducer = combineReducers(reducers)
const store = createStore(reducer)

HOCs and RenderProps

This module provides two ways to interact with the state on component level. One way is the usage of hocs the other way is the usage of RenderProps. Both technics tackle very similar problems and it's up to you, which way you prefer.

Here HOCs and RenderProps provide the same api. Every attribute a RenderProp Component can also be set in the configuation object of the hoc. Example:

import {withSearchForm, SearchForm} from 'redux-firebase-user'

// HOC
const ComponentWithHoc = withSearchForm({
  initialMail: 'user@example.com',
  initialPassword: 'password'
})(Component)

// you have also access to props:
const ComponentWithHoc = withSearchForm(props => ({
  initialMail: props.mail,
  initialPassword: props.password
}))(Component)

// RenderProp
const RenderPropComponent = () => (
  <div>
    <h1>Render Prop Component</h1>
    <SearchForm 
      initialMail='user@example.com'
      initialPassword='password'
      render={form => (
        <div>{/* your code with local scope */}</div>
      )}
    />
  <div>
)

Generally I would suggest to use a HOC, when the wrapped component is only build for this specific usecase, and to use a RenderProp in all other situations, because hocs can prevent prop collisions

withLoginForm & LoginForm

this RenderProp (HOC) provide functions and component props for a login form component. It has an internal state to manage the login credentials.

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb
initialMailstringthe mail the login form will be initialized with
initialPasswordstringthe password the login form will be initialized with

api

nametypedescription
loginfunclogin() logs the user in with the mail and password within the form
clearFormfuncclearForm() clears mail and password from the inner state
clearPasswordfuncclearPassword() clears only the password from the inner state
isFetchingboolwhether or not the login response is fetched
fetchErrorobj or nullholds the error object, if an error occoured during login
emailInputprops<input {...emailInput}/> props to manage an email input
passwordInputprops<input {...passwordInput}/> props to manage an password input
submitInputprops<input {...submitInput}/> props to manage the form submit input
formprops<form {...form}/> props to manage the wrapping from. performs login request when submitted

usage

import React from 'react'
import { withLoginForm, LoginForm } from 'redux-firebase-user'

// HOC

const Component = ({ form, emailInput, passwordInput, submitInput, fetchError }) => (
  <form {...form}>
    {/* every logic of how to interact with the state is handled by the injected component props 
        Nevertheless you can alway overwrite the default props by simply adding the jsx props*/}
    <input {...emailInput} placeholder='my placeholder'/><br/>
    <input {...passwordInput} /><br/>
    <input {...submitInput} />
    {
      // if the last request fails, an error will be displayed here
      fetchError && <div>{ fetchError.message }</div>
    }
  </form>
)

const ComponentWithLoginForm = withLoginForm({
  initialMail: 'user@example.com'
})(Component)

//alternatively you have access to the passed props:

const ComponentWithLoginForm = withLoginForm(props => ({
  initialMail: props.mail
}))(Component)

// RenderProp

const Component = () => (
  <div>
    <h1>Login Form</h1>
    <LoginForm initialMail='user@example.com' render={form => (
      <form {...form.form}>
        <input {...form.emailInput}/><br/>
        <input {...form.passwordInput} /><br/>
        <input {...form.submitInput} />
        {form.etchError && <div>{ form.fetchError.message }</div>}
      </form>
    )}/>
  </div>
)

withLoginRequest & LoginRequest

An alternative component to LoginForm without the component props but with authO login methods. Handles the login process

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb

api

nametypedescription
loginfunclogin(mail, password) logs the user in with the mail and password within the form
loginWithGooglefuncloginWithGoogle() authO login for Google. will open a popup to login
loginWithFacebookfuncloginWithFacebook() authO login for Facebook. will open a popup to login
loginWithGithubfuncloginWithGithub() authO login for Github. will open a popup to login
loginWithTwitterfuncloginWithTwitter() authO login for Twitter. will open a popup to login
loginWithGooglefuncloginWithGoogle() authO login for Google. will open a popup to login
fetchErrorobj or nullholds the error object, if an error occoured during login
isFetchingboolwhether or not the login response is fetched

usage

import React from 'react'
import { withLoginRequest, LoginRequest } from 'redux-firebase-user'

// HOC

class Component extends React.Component {
  state = { mail: '', pwd: '' }

  updateMail = e => this.setState({mail: e.target.value})
  updatePwd  = e => this.setState({pwd: e.target.value})

  render(){
    let {mail, pwd} = this.state
    let {login, fetchError} = this.props

    return (
      <form onSubmit={() => login(mail, pwd)}>
        <input type='text' value={mail} onChange={this.updateMail}/>
        <input type='password' value={pwd} onChange={this.updatePwd}/>
        <button>submit</button>
        {
          // if the last request fails, an error will be displayed here
          fetchError && <div>{ fetchError.message }</div>
        }
      </form>
    )
  }
}

const ComponentWithLoginRequest = withLoginRequest()(Component)

// RenderProp

class Component extends React.Component {
  state = { mail: '', pwd: '' }

  updateMail = e => this.setState({mail: e.target.value})
  updatePwd  = e => this.setState({pwd: e.target.value})

  render(){
    let {mail, pwd} = this.state

    return (
      <div>
        <h1>Login Form</h1>
        <LoginRequest render={req => (
          <form onSubmit={() => req.login(mail, pwd)}>
            <input type='text' value={mail} onChange={this.updateMail}/>
            <input type='password' value={pwd} onChange={this.updatePwd}/>
            <button>submit</button>
            {
              // if the last request fails, an error will be displayed here
              req.fetchError && <div>{ req.fetchError.message }</div>
            }
          </form>
        )}/>
      </div>
    )
  }
}

withSignupForm & SignupForm

this RenderProp (HOC) provide functions and component props for a signup form component. It has an internal state to manage the signup credentials.

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb
initialMailstringthe mail the signup form will be initialized with
initialPasswordstringthe password the signup form will be initialized with

api

nametypedescription
signupfuncsignup() signs the user up with the mail and password within the form
clearFormfuncclearForm() clears mail and password from the inner state
clearPasswordfuncclearPassword() clears only the password from the inner state
isFetchingboolwhether or not the signup response is fetched
fetchErrorobj or nullholds the error object, if an error occoured during signup
emailInputprops<input {...emailInput}/> props to manage an email input
passwordInputprops<input {...passwordInput}/> props to manage an password input
submitInputprops<input {...submitInput}/> props to manage the form submit input
formprops<form {...form}/> props to manage the wrapping from. performs signup request when submitted

usage

import React from 'react'
import { withSignupForm, SignupForm } from 'redux-firebase-user'

// HOC

const Component = ({ form, emailInput, passwordInput, submitInput, fetchError }) => (
  <form {...form}>
    {/* every logic of how to interact with the state is handled by the injected component props 
        Nevertheless you can alway overwrite the default props by simply adding the jsx props*/}
    <input {...emailInput} placeholder='my placeholder'/><br/>
    <input {...passwordInput} /><br/>
    <input {...submitInput} />
    {
      // if the last request fails, an error will be displayed here
      fetchError && <div>{ fetchError.message }</div>
    }
  </form>
)

const ComponentWithSignupForm = withSignupForm({
  initialMail: 'user@example.com'
})(Component)

//alternative you have access to the passed props:

const ComponentWithSignupForm = withSignupForm(props => ({
  initialMail: props.mail
}))(Component)

// RenderProp

const Component = () => (
  <div>
    <h1>Signup Form</h1>
    <SignupForm initialMail='user@example.com' render={form => (
      <form {...form.form}>
        <input {...form.emailInput}/><br/>
        <input {...form.passwordInput} /><br/>
        <input {...form.submitInput} />
        {form.etchError && <div>{ form.fetchError.message }</div>}
      </form>
    )}/>
  </div>
)

withSignupRequest & SignupRequest

An alternative component to SignupForm without the component props. Handles the signup process

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb

api

nametypedescription
signupfuncsignup(mail, password) signs the user up with the mail and password within the form
fetchErrorobj or nullholds the error object, if an error occoured during signup
isFetchingboolwhether or not the signup response is fetched

usage

import React from 'react'
import { withSignupRequest, SignupRequest } from 'redux-firebase-user'

// HOC

class Component extends React.Component {
  state = { mail: '', pwd: '' }

  updateMail = e => this.setState({mail: e.target.value})
  updatePwd  = e => this.setState({pwd: e.target.value})

  render(){
    let {mail, pwd} = this.state
    let {login, fetchError} = this.props

    return (
      <form onSubmit={() => login(mail, pwd)}>
        <input type='text' value={mail} onChange={this.updateMail}/>
        <input type='password' value={pwd} onChange={this.updatePwd}/>
        <button>submit</button>
        {
          // if the last request fails, an error will be displayed here
          fetchError && <div>{ fetchError.message }</div>
        }
      </form>
    )
  }
}

const ComponentWithSignupRequest = withSignupRequest()(Component)

// RenderProp

class Component extends React.Component {
  state = { mail: '', pwd: '' }

  updateMail = e => this.setState({mail: e.target.value})
  updatePwd  = e => this.setState({pwd: e.target.value})

  render(){
    let {mail, pwd} = this.state

    return (
      <div>
        <h1>Signup Form</h1>
        <SignupRequest render={req => (
          <form onSubmit={() => req.login(mail, pwd)}>
            <input type='text' value={mail} onChange={this.updateMail}/>
            <input type='password' value={pwd} onChange={this.updatePwd}/>
            <button>submit</button>
            {
              // if the last request fails, an error will be displayed here
              req.fetchError && <div>{ req.fetchError.message }</div>
            }
          </form>
        )}/>
      </div>
    )
  }
}

withLogoutForm & LogoutForm

this RenderProp (HOC) provide functions and component props for a login form component. It has an internal state to manage the login credentials.

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb

api

nametypedescription
logoutfunclogout() logs the user out
isFetchingboolwhether or not the logout response is fetched
fetchErrorobj or nullholds the error object, if an error occoured during logout
logoutButtonprops<button {...logoutButton}/> props to manage an logout button

usage

import React from 'react'
import { withLogoutForm, LogoutForm } from 'redux-firebase-user'

// HOC

const Component = ({ logoutButton, fetchError }) => (
  <div>
    <button {...logoutButton}>logout</button>
    {
      // if the last request fails, an error will be displayed here
      fetchError && <div>{ fetchError.message }</div>
    }
  </div>
)

const ComponentWithLogoutForm = withLogoutForm()(Component)

// RenderProp

const Component = () => (
  <div>
    <h1>Logout Form</h1>
    <LogoutForm render={form => (
      <div>
        <button {...logoutButton}>logout</button>
        {form.etchError && <div>{ form.fetchError.message }</div>}
      </div>
    )}/>
  </div>
)

withLogoutRequest & LogoutRequest

An alternative component to LogoutForm without the component props. Handles the logout process

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb

api

nametypedescription
logoutfuncsignup(mail, password) loggs the user out
fetchErrorobj or nullholds the error object, if an error occoured during logout
isFetchingboolwhether or not the logout response is fetched

usage

import React from 'react'
import { withLogoutRequest, LogoutRequest } from 'redux-firebase-user'

// 

const Component = ({logout}) => (
  <button onClick={logout}>logout</button>
)


const ComponentWithLogoutRequest = withLogoutRequest()(Component)

// RenderProp

const Component = () => (
  <LogoutRequest render={req => (
    <button onClick={req.logout}>logout</button>
  )}/>
)

withUser & User

This RenderProp (hoc) injects user data and can tell whether or not the user is logged in

props

nametypedescription
renderfuncrequired only for render props. cb to render the component. all atributes listed below in the api will be given as parameter to the cb

api

nametypedescription
profileobject or nullholds the user object from firebase
isLoggedInboolwhether or not the user is logged in

usage

import React from 'react'
import { withUser, User } from 'redux-firebase-user'

// 

const Component = ({isLoggedIn, profile}) => (
  <div>
    <div>logged in: {isLoggedIn ? 'yes' : 'no'}</div>
    <div>user id: {profile && profile.uid}</div>
  </div>
)


const ComponentWithLogoutRequest = withUser()(Component)

// RenderProp

const Component = () => (
  <div>
    <h1>User Stats</h1>
    <User render={user => (
      <div>
        <div>logged in: {user.isLoggedIn ? 'yes' : 'no'}</div>
        <div>user id: {user.profile && user.profile.uid}</div>
      </div>
    )}/>
  </div>
)

Components

AuthOButtons

The following AuthO button components are provided:

  • GoogleAuthOButton
  • FacebookAuthOButton
  • GithubAuthOButton
  • TwitterAuthOButton
import React from 'react'
import {
  GoogleAuthOButton, 
  GithubAuthOButton, 
  FacebookAuthOButton, 
  TwitterAuthOButton
} from 'redux-firebase-user'


export const LoginForm = () => (
  <div>
    <GoogleAuthOButton/>
    <GithubAuthOButton/>
    <FacebookAuthOButton/>
    <TwitterAuthOButton/>
  </div>
)

export default LoginForm

All of these buttons share the same propTypes

nametypedefaultdescription
backgroundstringdepends on buttonthe background color of the button
colorstringwhitesmokethe text and icon color
sizestring / number1.0the size of the whole button (example: "1.5" or 0.5)
widthstring / numberautothe width of the button (number is in pixel)
hideTextboolfalsewhether or not a text should be displayed. Set to true, if you only want to show the icon
textstring"Login with METHOD"the button label
childrenstringsame as text (if both set, children will win)

Selectors

Although this library provides serveral selectors, the recommended way to get a shape of the state is via hocs. But if no hoc fulfill your needs, you are also able to access the user state by a set of serveral selectors. All of them accepts the global state (not the user state) as the first state argument and optional further arguments. These selectors can be accessed via

import { getUser, isLoggedIn } from 'redux-firebase-user'

let user = getUser(state)
let loggedIn = isLoggedIn(state)

Here is the full list of all available selectors:

nameargumentsreturndescription
getUserstatenull / objectreturns the login details of the currently logged in user
isLoggedInstateboolreturns whether or not the user is currently logged in
isFetchingLoginstateboolreturns whether or not the user currently trys to log in
loginFetchFailedstatebooltrue if the last login failed
getLoginFetchErrorstatenull / stringholds the error, if the last login failed
isFetchingLogoutstateboolreturns whether or not the user currently trys to log out
logoutFetchFailedstatebooltrue if the last logout failed
getLogoutFetchErrorstatenull / stringholds the error, if the last logout failed
isFetchingSignupstateboolreturns whether or not the user currently trys to sign up
signupFetchFailedstatebooltrue if the last signup failed
getSignupFetchErrorstatenull / stringholds the error, if the last signup failed

ActionTypes

These are the actionTypes this module uses to handle reducer state change:

namedescription
user/FETCH_LOGIN_REQUESTUser trys to login with emailAndPassword or via a autO provider
user/FETCH_LOGIN_SUCCESSUser successfully logged in with emailAndPassword or via a autO provider
user/FETCH_LOGIN_FAILUREUser failed to login with emailAndPassword or via a autO provider
user/FETCH_SIGNUP_REQUESTUser trys to signup with emailAndPassword
user/FETCH_SIGNUP_SUCCESSUser successfully signed up with emailAndPassword
user/FETCH_SIGNUP_FAILUREUser failed to signup with emailAndPassword
user/FETCH_LOGOUT_REQUESTUser trys to logout
user/FETCH_LOGOUT_SUCCESSUser successfully logged out
user/FETCH_LOGOUT_FAILUREUser failed to logout
// your reducer
import { actionTypes as t } from 'redux-firebase-user'

export default function countReducer = (state = 0, action) {
  switch (action.type) {
    
    case t.FETCH_LOGOUT_SUCCESS: return 0

    default: return state
  }
}

Actions

import { login, logout, signup } from 'redux-firebase-user'
import { 
  loginWithGoogle, 
  loginWithFacebook, 
  loginWithGithub, 
  loginWithTwitter 
} from 'redux-firebase-user'

// login user
dispatch(login('user@example.com', 'password'))

// logout user
dispatch(logout())

// signup user
dispatch(signup('user@example.com', 'password'))

// authO login
dispatch(loginWithGoogle())
dispatch(loginWithFacebook())
dispatch(loginWithGithub())
dispatch(loginWithTwitter())
1.0.1

6 years ago

0.3.1

7 years ago

0.3.0

7 years ago

0.2.1

7 years ago

0.2.0

7 years ago

0.1.0

7 years ago

0.0.1

7 years ago

0.0.0

7 years ago