Real-Time React with Firebase

Simen Brekken (@simenbrekken)

Einar Löve (@einarlove)

github.com/unfold

Our latest venture

  • Service for managing people at construction sites
  • Complex node-based data structure
  • Many relationships
  • Clients and workers (auth, notifications, SMS etc.)
  • Frequent changes, updates need to be real-time

Reading & Writing

  • REST
    • Polling is inefficient
    • Large request overhead
  • WebSockets
    • Efficient real-time updates
    • Server responsible for notifying affected clients
  • Hard to implement optimized differential updates

Relay & GraphQL

  • Efficient incremental updates
  • Not yet released
  • No support for real-time updates

Other potential solutions

Firebase

  • Hosted service means less infrastructure work
  • Nice extras
    • Very fast optimistic updates

    • Pluggable authentication

    • Field-level authorization

Firebase

  • Listen to and modify any location
  • Changes are broadcast to other clients in real-time

Firebase & React

  • Derive application state from Firebase
  • Cheap listeners
<Project>
  <Tasks>
    <Task>
      <Deadline />
      <Responsible>
        <UserPicture />
        <UserName />
      </Responsible>
    </Task>
  </Tasks>
</Project>
projects/1
projects/1/tasks
projects/1/tasks/1
projects/1/tasks/1/deadline
projects/1/responsible
users/mike/name
users/mike/picture/url

const firebase = new Firebase('https://my-app.firebaseio.com');

class User extends React.Component {
  componentDidMount() {
    const userRef = firebase.child('users/mike');
    const listener = userRef.on('value', snapshot => (
      this.setState({ user: snapshot.val() });
    ));

    this.unsubscribe = () => userRef.off('value', listener);
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  render() {
    const { name, phone } = this.state.user;

    return <div>Name: {name} ({phone})</div>;
  }
}

Firebase & React

Mike's got a new task

<User userId="mike">
  <Task taskId={user.currentTaskId}>
    <Project projectId={task.projectId}>
      <UserPicture userId={project.ownerId} />
      <UserName userId={project.ownerId} />
    </Project>
  </Task>
</User>
users/${userId}
tasks/${currentTaskId}
projects/${projectId}
users/${userId}/picture/url
users/${userId}/name

Authentication

REST Image Upload

Firebase Image Upload

Growth challenges

  • Managing listeners hard when imperative
  • Hard to refactor
  • Being declarative is predictable and powerful

React + Firebase

  • Declarative
  • Higher-order components
  • Efficient listener management
  • Open-source today (MIT)
import { connect } from 'react-firebase';

const mapPropsToSubscriptions = () => ({
  count: 'count' 
});

const mapFirebaseToProps = firebase => ({
  setCount: count => firebase.child('count').set(count),
});

const Count = ({ count, setCount }) => (
  <div>
    <p>Count: {count || 0}</p>

    <button onClick={() => setCount(count - 1)}>Decrement</button>
    <button onClick={() => setCount(count + 1)}>Increment</button>
  </div>
);

export default connect(mapPropsToSubscriptions, mapFirebaseToProps)(Count);

react-firebase

Firebase & Others

  • Plays nicely with existing technologies
  • Great for caching

(press 'a' to become the game host)

Questions?

Simen Brekken (@simenbrekken)

Einar Löve (@einarlove)

github.com/unfold

Simen Brekken (@simenbrekken)

Einar Löve (@einarlove)

github.com/unfold

Real-Time React with Firebase

By Simen Brekken

Real-Time React with Firebase

  • 1,527