generator-react-firebase v2.1.0-alpha
generator-react-firebase
Yeoman generator for starting projects using React and Firebase (Redux optional)
Installation
Install Yeoman and generator-react-firebase using npm (we assume you have pre-installed node.js):
npm install -g yo generator-react-firebaseGetting Started
- Create a project folder and enter it:
mkdir myProject && cd myProject - Generate project:
yo react-firebase(project will be named after current folder) - Start application by running
npm start
Project will default to being named with the name of the folder that it is generated within (in this case myProject)
Whats Next
- Checkout and understand
src/config.js. This was generated for you for your local development environment, but is is ignored from git tracking (within.gitignore). You can have different settings within this file based on environment or if multiple developers are running the same code. - Tryout the Sub Generators
- Tryout Firestore (you can generate a new project with
yesas the answer toDo you want to use Firestore). Things work mostly the same, but it runs throughredux-firestore.
Features
- firebase-functions v1 (including support within function sub-generator)
- React v16.3
- Material-UI v1 application styling including Navbar
- Full Authentication (through Email, Google or Github)
- Login/Signup Pages with input validation
- Route protection (only view certain pages when logged in)
- Account Page
- Automatic Build/Deploy config for multiple CI Providers including:
- Gitlab (uses pipelines)
- Travis
Uses
- react - Rendering + Components
- react-router - Routing (including async route loading)
- material-ui - Google Material Styling React Components (with option to opt out of Version 1)
- eslint - Linting (also implements
prettier) - webpack-dashboard - Improve CLI experience for Webpack
When opting into redux
- redux - Client Side state optional
- react-redux-firebase - Easily Persist results of Firebase queries to redux state
- redux-auth-wrapper - Easily create HOCs for route/component protection based on auth state
- redux-form - Form input validation + state
- redux-form-material-ui - Material UI components that work nicely with redux-form
Generated Project
Project outputted from generator has a README explaining the full structure and details specific to settings you choose. The following scripts are included:
npm run <script> | Description |
|---|---|
start | Serves your app at localhost:3000 |
build | Builds the application to ./dist |
test | Runs unit tests with Karma. See testing |
test:watch | Runs test in watch mode to re-run tests when changed |
lint | Lints the project for potential errors |
lint:fix | Lints the project and fixes all correctable errors |
View the example application README for more details.
Production
Build code before deployment by running npm run build. There are multiple options below for types of deployment, if you are unsure, checkout the Firebase section.
Deployment
Firebase
- Login to Firebase (or Signup if you don't have an account) and create a new project
- Install cli:
npm i -g firebase-tools - Choose to go to a either the CI section(suggested) or the Manual section
CI
If opting into Travis-CI, config is included within travis.yml that uses firebase-ci to simplify the CI deployment process. All that is required is providing authentication with Firebase:
- Select yes to question
Would to include config for Travis CI?when generating - Select
Firebaseunder deploy options - Login:
firebase login:cito generate an authentication token (will be used to give Travis-CI rights to deploy on your behalf) - Set
FIREBASE_TOKENenvironment variable within Travis-CI environment - Run a build on Travis-CI
- To deploy to different Firebase instances for different branches (i.e.
prod), changecisettings within.firebaserc
Settings for each environment can be provided through the .firebaserc file.
For more options on CI settings checkout the firebase-ci docs
Manual
- Run
firebase:login - Initialize project with
firebase initthen answer:
- What file should be used for Database Rules? ->
database.rules.json - What do you want to use as your public directory? ->
build - Configure as a single-page app (rewrite all urls to /index.html)? ->
Yes - What Firebase project do you want to associate as default? -> your Firebase project name
- Build Project:
npm run build - Confirm Firebase config by running locally:
firebase serve(make sure you runnpm run buildfirst) - Deploy to firebase:
firebase deploy
AWS S3
Selecting AWS S3 from the deploy options when running the generator adds deploy configs in .travis.yml.
- Select yes to question
Would to include config for Travis CI?when generating - Select
AWSunder deploy options - Get your AWS Key and Secret from the AWS Console Credentials page
- Set the following environment vars within the Travis-CI repo settings page:
AWS_KEY- Your AWS keyAWS_SECRET- Your AWS secretS3_BUCKET- Your S3 Bucket
Heroku
Selecting Heroku from the deploy options when running the generator adds a Procfile. If you choose yes when offered travis, as deploy configs will be included in .travis.yml for out of the box deployment.
- Select yes to question
Would to include config for Travis CI?when generating - Select
Herokuunder deploy options - Enable Repo on Travis-CI Account
- Get API Key from Heroku Dashboard
- Create a new App (this name will be used in travis env var)
- Set the following environment vars within the Travis-CI repo settings page:
HEROKU_KEY- Your Heroku API keyHEROKU_APP- Your Heroku App name
Sub generators
Sub generators are included to help speed up the application building process. You can run a sub-generator by calling yo react-firebase:<name of sub-generator> <param1>.
Example: To call the component sub-generator with "SomeThing" as the first parameter write: yo react-firebase:component SomeThing
Path Argument
Another argument can be passed to sub generators (unless otherwise noted) to provide the base path in which you would like to run the generator (starts from src). For example: yo react-firebase:component Car routes/Project runs the component generator within the Project route folder meaning that the component will be added to routes/Project/components instead of the top level src/components folder.
Function
Generates a Cloud Function allowing the user to specify trigger type (from HTTPS, Firestore, RTDB, Auth, or Storage)
A component is best for things that will be reused in multiple places. Our example
command
yo react-firebase:function uppercaser
result
/functions
--/uppercaser
----index.jsFor firebase-functions <v1.0.0:
/functions/uppercaser/index.js:
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import { to } from 'utils/async'
/**
* @param {functions.Event} event - Function event
* @return {Promise}
*/
async function uppercaserEvent(event) {
const eventData = event.data.val()
const params = event.params
const ref = admin.database().ref('responses')
const [writeErr, response] = await to(ref.push(eventData))
if (writeErr) {
console.error('Error writing response:', writeErr.message || writeErr)
throw writeErr
}
return response
}
/**
* @name uppercaser
* Cloud Function triggered by Real Time Database Event
* @type {functions.CloudFunction}
*/
export default functions.database
.ref('/users/{userId}')
.onUpdate(uppercaserEvent)For firebase-functions >=v1.0.0:
/functions/uppercaser/index.js:
import * as functions from 'firebase-functions'
import * as admin from 'firebase-admin'
import { to } from 'utils/async'
/**
* @param {functions.Event} event - Function event
* @return {Promise}
*/
async function uppercaserEvent(change, context) {
// const { params, auth, timestamp } = context
// const { before, after } = change
const ref = admin.database().ref('responses')
const [writeErr, response] = await to(ref.push({ hello: 'world' }))
if (writeErr) {
console.error('Error writing response:', writeErr.message || writeErr)
throw writeErr
}
return response
}
/**
* @name uppercaser
* Cloud Function triggered by Real Time Database Event
* @type {functions.CloudFunction}
*/
export default functions.database
.ref('/users/{userId}')
.onUpdate(uppercaserEvent)Note: This sub-generator does not support the Path Argument (functions are already placed within a folder matching their name).
Component
Generates a React component along with an option matching style file (either Javascript or SCSS) and places it within /components.
A component is best for things that will be reused in multiple places. Our example
command
yo react-firebase:component Car
result
/app
--/components
----/Car
------index.js
------Car.enhancer.js // optional
------Car.styles.js // optional (Localized MUI Styling)
------Car.js
------Car.scss // option (SCSS File)/app/components/Car.js:
import React from 'react'
import PropTypes from 'prop-types'
import classes from './Car.scss'
export const Car = ({ car }) => (
<div className={classes.container}>
<span>Car Component</span>
<pre>{JSON.stringify(car, null, 2)}</pre>
</div>
)
export default CarNOTE: Option to use Javascript file for styles is only offered if @material-ui/core is included in package.json
Form
Generates a Redux Form wrapped React component along with a matching scss file and places it within /components.
command
yo react-firebase:form Car
or
yo react-firebase:form CarForm
result
/app
--/components
----/CarForm
------index.js
------CarForm.enhancer.js
------CarForm.js
------CarForm.scss/app/components/CarForm.js:
import React from 'react'
import PropTypes from 'prop-types'
import classes from './Car.scss'
export const CarForm = ({ car }) => (
<div className={classes.container}>
<span>CarForm Component</span>
<pre>{JSON.stringify(car, null, 2)}</pre>
</div>
)
export default CarFormEnhancer
Generates an enhancer for a react component. Also includes an index file that wraps the component in the enhancer.
command
yo react-firebase:enhancer Project
result
/app
--/components
----/Project
------index.js
------Project.enhancer.jsRoute
Generates a React component along with a matching component (which has an scss file, an enhancer, and its own index file).
command
yo react-firebase:route Project
result
/app
--/routes
----/Project
------index.js
------components
--------ProjectPage
----------index.js
----------Project.enhancer.js // optional
----------Project.js
----------Project.scssModule
Generates a React component along with a matching component (which has an scss file, an enhancer, and its own index file).
command
yo react-firebase:module notification
result
/app
--/modules
----/notification
------components
------actions.js
------actionTypes.js
------index.js
------reducer.jsNote: This sub-generator does not support the Path Argument (functions are already placed within a folder matching their name).
Examples
Complete examples of generator output available in Examples
- react-firebase-redux example -
reduxand Firebase Real Time Database - redux-firestore -
reduxand Firestore - react-firebase example - Firebase Real Time Database
For full projects built out using this as a starting place, check the next section.
Projects Started Using This
- fireadmin.io - Application for Managing Firebase Applications. Includes support for multiple environments and data migrations.
- devshare.io - Codesharing site based on Firebase's Firepad and Realtime Database
- react-redux-firebase material example - Shows usage of react-redux-firebase with material-ui
- react-redux-firebase firestore example - Shows usage of react-redux-firebase with firestore
open an issue or reach out over gitter if you would like your project to be included
FAQ
Why node
8instead of a newer version? Cloud Functions runtime was still on8, which is why that is what is used for the suggested build version as well as the version used when building within CI.Why
enhancersovercontainers? - For many reasons, here are just a few:
- separates concerns to have action/business logic move to enhancers (easier for future modularization + optimization)
- components remain "dumb" by only receiving props which makes them more portable
- smaller files which are easier to parse
- functional components can be helpful (along with other tools) when attempting to optimize things
Where are the settings for changing how my project deploys through Continious integration?
Within
.firebasercunder thecisection. These settings are loaded by firebase-ciHow do override
react-redux-firebaseandredux-firestoreconfiguration based on environment? Like adding logging only to staging?Add the following to
.firebasercunder the branch associated with the environment you wish to change:"reduxFirebase": { "userProfile": "users", "enableLogging": false, "updateProfileOnLogin": false }Should look end up looking similar to the following:
"master": { "env": "staging", "firebase": { "apiKey": "${STAGE_FIREBASE_API_KEY}", "authDomain": "some-project.firebaseapp.com", "databaseURL": "https://some-project.firebaseio.com", "projectId": "some-project", "storageBucket": "some-project.appspot.com" }, "reduxFirebase": { "enableLogging": true } }
In the future
- Option to include tests when using sub-generators
- Airbnb linting option (currently only
standard) - Option to use simple file structure instead of fractal pattern
- Open to ideas
License
MIT © Prescott Prue
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago