Skip to content

Latest commit

 

History

History
139 lines (113 loc) · 3.68 KB

getting-started.md

File metadata and controls

139 lines (113 loc) · 3.68 KB

Use

import { createStore, combineReducers, compose } from 'redux';
import { reduxFirestore, firestoreReducer } from 'redux-firestore';
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';
import 'firebase/firestore';

const firebaseConfig = {}; // from Firebase Console
const rfConfig = {}; // optional redux-firestore Config Options

// Initialize firebase instance
firebase.initializeApp(firebaseConfig);
// Initialize Cloud Firestore through Firebase
firebase.firestore();

// Add reduxFirestore store enhancer to store creator
const createStoreWithFirebase = compose(
  reduxFirestore(firebase, rfConfig), // firebase instance as first argument, rfConfig as optional second
)(createStore);

// Add Firebase to reducers
const rootReducer = combineReducers({
  firestore: firestoreReducer,
});

// Create store with reducers and initial state
const initialState = {};
const store = createStoreWithFirebase(rootReducer, initialState);

Then pass store to your component's context using react-redux's Provider:

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';

render(
  <Provider store={store}>
    <MyRootComponent />
  </Provider>,
  rootEl,
);

Debugging

Enable browser debugging to troubleshoot dataflow issues

localStore.debug='rrf:*'
localStore.debug='rrf:cache'
localStore.debug='rrf:mutate'
localStore.debug='rrfVerbose:*'

Components

Functional Components

It is common to make react components "functional" meaning that the component is just a function instead of being a class which extends React.Component. This can be useful, but can limit usage of lifecycle hooks and other features of Component Classes. recompose helps solve this by providing Higher Order Component functions such as withContext, lifecycle, and withHandlers.

import { connect } from 'react-redux';
import {
  compose,
  withHandlers,
  lifecycle,
  withContext,
  getContext,
} from 'recompose';

const withStore = compose(
  withContext({ store: PropTypes.object }, () => {}),
  getContext({ store: PropTypes.object }),
);

const enhance = compose(
  withStore,
  withHandlers({
    loadData: (props) => () => props.store.firestore.get('todos'),
    onDoneClick: (props) => (key, done = false) =>
      props.store.firestore.update(`todos/${key}`, { done }),
    onNewSubmit: (props) => (newTodo) =>
      props.store.firestore.add('todos', { ...newTodo, owner: 'Anonymous' }),
  }),
  lifecycle({
    componentDidMount(props) {
      props.loadData();
    },
  }),
  connect(({ firebase }) => ({
    // state.firebase
    todos: firebase.ordered.todos,
  })),
);

export default enhance(SomeComponent);

For more information on using recompose visit the docs

Component Class
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { watchEvents, unWatchEvents } from './actions/query';
import { getEventsFromInput, createCallable } from './utils';

class Todos extends Component {
  static contextTypes = {
    store: PropTypes.object.isRequired,
  };

  componentDidMount() {
    const { firestore } = this.context.store;
    firestore.get('todos');
  }

  render() {
    return (
      <div>
        {todos.map((todo) => (
          <div key={todo.id}>{JSON.stringify(todo)}</div>
        ))}
      </div>
    );
  }
}

export default connect((state) => ({
  todos: state.firestore.cache.todos.docs,
}))(Todos);