Setup @react-firebase/database

If you haven't, install the firebase JS client.

yarn add firebase
# Or
npm i firebase

Install @react-firebase/database

yarn add @react-firebase/database # or npm i @react-firebase/database

Change PROJECT_NAME to your project name and grab your firebase config here :

https://console.firebase.google.com/project/PROJECT_NAME/settings/general/

Your config file should look something like this :

// Firebase Config
const config = {
  apiKey: "API_KEY",
  projectId: "PROJECT_ID",
  databaseURL: "DATABASE_URL",
  authDomain: "AUTH_DOMAIN",
  // OPTIONAL
  storageBucket: "STORAGE_BUCKET",
  messagingSenderId: "MESSAGING_SENDER_ID"
};

Usage

Components

  • FirebaseDatabaseProvider
  • FirebaseDatabaseNode
  • FirebaseDatabaseMutation
  • FirebaseDatabaseTransaction

Place a FirebaseDatabaseProvider component at the top level of your app (anywhere as long as it's above the other Realtime Database components).

import { FirebaseDatabaseProvider } from "@react-firebase/database";
// Before
function App() {
  return (
    <div>
      This is my app <SomeOtherComponent />
    </div>
  );
}

// After
function App() {
  return (
    <FirebaseDatabaseProvider>
      <div>
        This is my app
        <SomeOtherComponent />
      </div>
    </FirebaseDatabaseProvider>
  );
}

If you need to authenticate to access your data, check out @react-firebase/auth

Firebase Database Node

Check API for a list of supported props.

Read data from Firebase example

Sample Code

class App extends React.Component<any, AppState> {
  state = {
    limit: 2
  };
  render() {
    return (
      <div style={styles}>
        <FirebaseDatabaseProvider firebase={firebase} {...config}>
          <div>
            <FirebaseDatabaseNode
              path="user_bookmarks/"
              limitToFirst={this.state.limit}
              // orderByKey
              orderByValue={"created_on"}
            >
              {d => {
                return (
                  <React.Fragment>
                    <pre>Path {d.path}</pre>
                    <pre style={{ height: 300, overflow: "auto" }}>
                      Value {s(d.value)}
                    </pre>
                    <button
                      onClick={() => {
                        this.setState(state => ({ limit: state.limit + 2 }));
                      }}
                    >
                      Load more
                    </button>
                  </React.Fragment>
                );
              }}
            </FirebaseDatabaseNode>
          </div>
        </FirebaseDatabaseProvider>
      </div>
    );
  }
}

Sandbox

Firebase Database Mutation

The FirebaseDatabaseMutation allows you to render components that run Firebase mutations (update, set, push).

A setMutation function that returns a promise is provided to the children function.

FirebaseDatabaseMutation needs 3 props :

  • path: string
  • operation: "update" | "set" | "push"
  • children:

    | ( { runMutation: (value:any) => Promise<{key?:string}> } ) => ReactNode | | :---------------------------------------------------------------------- |

Sample Code

class MutationExample extends React.Component {
  state = {
    pushedKey: ""
  };
  render() {
    const { state } = this;
    return (
      <React.Fragment>
        <FirebaseDatabaseMutation type="push" path={path}>
          {({ runMutation }) => {
            return (
              <div>
                <button
                  data-testid="test-push"
                  onClick={async () => {
                    const { key } = await runMutation({ TEST: "DATA" });
                    this.setState({ pushedKey: key });
                  }}
                >
                  Push
                </button>
              </div>
            );
          }}
        </FirebaseDatabaseMutation>
        {state.pushedKey !== "" && (
          <div>
            <div data-testid="test-push-result">{state.pushedKey}</div>
            <div>
              <FirebaseDatabaseNode path={`${path}/${state.pushedKey}`}>
                {({ value }) => <pre>{s(value)}</pre>}
              </FirebaseDatabaseNode>
              <FirebaseDatabaseMutation
                type="set"
                path={`${path}/${state.pushedKey}`}
              >
                {({ runMutation }) => (
                  <button
                    onClick={async () => {
                      runMutation(null);
                      this.setState({ pushedKey: "" });
                    }}
                  >
                    Delete
                  </button>
                )}
              </FirebaseDatabaseMutation>
            </div>
          </div>
        )}
      </React.Fragment>
    );
  }
}

Sandbox

Firebase Database Transaction

Suppose you have a shared counter that many can increment. To avoid race conditions, use transactions.

FirebaseDatabaseTransaction needs 2 props:

  • path: string
  • children:

    | ( { runTransaction: ({ reducer: (value:any)=>any }) => Promise<{key?:string}> } ) => ReactNode | | :--------------------------------------------------------------------------------------------- |