Skip to content

Latest commit

 

History

History
 
 

database

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

React Firebase Hooks - Realtime Database

React Firebase Hooks provides convenience listeners for lists and values stored within the Firebase Realtime Database. The hooks wrap around the onX(...) method.

In addition to returning the list or value, the hooks provide an error and loading property to give a complete lifecycle for loading and listening to the Realtime Database.

All hooks can be imported from hooked-on-firebase/database, e.g.

import { useList } from 'hooked-on-firebase/database';

List of Realtime Database hooks:

Additional functionality:

useList

const [snapshots, loading, error] = useList(reference);

Retrieve and monitor a list value in the Firebase Realtime Database.

The useList hook takes the following parameters:

  • reference: (optional) database.Reference for the data you would like to load

Returns:

  • snapshots: an array of database.DataSnapshot, or undefined if no reference is supplied
  • loading: a boolean to indicate if the data is still being loaded
  • error: Any Error returned by Firebase when trying to load the data, or undefined if there is no error

Full Example

import { ref, getDatabase } from 'firebase/database';
import { useList } from 'hooked-on-firebase/database';

const database = getDatabase(firebaseApp);

const DatabaseList = () => {
  const [snapshots, loading, error] = useList(ref(database, 'list'));

  return (
    <div>
      <p>
        {error && <strong>Error: {error}</strong>}
        {loading && <span>List: Loading...</span>}
        {!loading && snapshots && (
          <React.Fragment>
            <span>
              List:{' '}
              {snapshots.map((v) => (
                <React.Fragment key={v.key}>{v.val()}, </React.Fragment>
              ))}
            </span>
          </React.Fragment>
        )}
      </p>
    </div>
  );
};

useListKeys

const [keys, loading, error] = useListKeys(reference);

As useList, but this hooks extracts the database.DataSnapshot.key values, rather than the the database.DataSnapshots themselves.

The useListKeys hook takes the following parameters:

  • reference: (optional) database.Reference for the data you would like to load

Returns:

  • keys: an array of string, or undefined if no reference is supplied
  • loading: a boolean to indicate if the data is still being loaded
  • error: Any Error returned by Firebase when trying to load the data, or undefined if there is no error

useListVals

const [values, loading, error] = useListVals<T> (reference, options);

As useList, but this hook extracts a typed list of the database.DataSnapshot.val() values, rather than the the database.DataSnapshots themselves.

The useListVals hook takes the following parameters:

  • reference: (optional) database.Reference for the data you would like to load
  • options: (optional) Object with the following parameters:
    • keyField: (optional) string field name that should be populated with the database.DataSnapshot.id property in the returned values.
    • refField: (optional) string field name that should be populated with the database.DataSnapshot.ref property.
    • transform: (optional) a function that receives the raw database.DataSnapshot.val() for each item in the list to allow manual transformation of the data where required by the application. See Transforming data below.

Returns:

  • values: an array of T, or undefined if no reference is supplied
  • loading: a boolean to indicate if the data is still being loaded
  • error: Any Error returned by Firebase when trying to load the data, or undefined if there is no error

useObject

const [snapshot, loading, error] = useObject(reference);

Retrieve and monitor an object or primitive value in the Firebase Realtime Database.

The useObject hook takes the following parameters:

  • reference: (optional) database.Reference for the data you would like to load

Returns:

  • snapshot: a database.DataSnapshot, or undefined if no reference is supplied
  • loading: a boolean to indicate if the data is still being loaded
  • error: Any Error returned by Firebase when trying to load the data, or undefined if there is no error

Full Example

import { ref, getDatabase } from 'firebase/database';
import { useObject } from 'hooked-on-firebase/database';

const database = getDatabase(firebaseApp);

const DatabaseValue = () => {
  const [snapshot, loading, error] = useObject(ref(database, 'value'));

  return (
    <div>
      <p>
        {error && <strong>Error: {error}</strong>}
        {loading && <span>Value: Loading...</span>}
        {snapshot && <span>Value: {snapshot.val()}</span>}
      </p>
    </div>
  );
};

useObjectVal

const [value, loading, error] = useObjectVal<T> (reference, options);

As useObject, but this hook returns the typed contents of database.DataSnapshot.val(), rather than the the database.DataSnapshot itself.

The useObjectVal hook takes the following parameters:

  • reference: (optional) database.Reference for the data you would like to load
  • options: (optional) Object with the following parameters:
    • keyField: (optional) string field name that should be populated with the database.DataSnapshot.key property in the returned value.
    • refField: (optional) string field name that should be populated with the database.DataSnapshot.ref property.
    • transform: (optional) a function that receives the raw database.DataSnapshot.val() to allow manual transformation of the data where required by the application. See Transforming data below.

Returns:

  • value: a T, or undefined if no reference is supplied
  • loading: a boolean to indicate if the data is still being loaded
  • error: Any FirebaseError returned by Firebase when trying to load the data, or undefined if there is no error

Transforming data

Firebase allows a restricted number of data types in the Realtime Database, which may not be flexible enough for your application. Both useListVals and useObjectVal support an optional transform function which allows the transformation of the underlying Firebase data into whatever format the application require, e.g. a Date type.

transform?: (val: any) => T;

The transform function is passed a single row of a data, so will be called once when used with useObjectVal and multiple times, when used with useListVals.

The transform function will not receive the key or ref values referenced in the properties named in the keyField or refField options, nor it is expected to produce them. Either or both, if specified, will be merged afterwards.

If the transform function is defined within your React component, it is recomended that you memoize the function to prevent unnecessry renders.

Full Example

type SaleType = {
  idSale: string,
  date: Date, // <== it is declared as type Date which Firebase does not support.
  // ...Other fields
};
const options = {
  keyField: 'idSale',
  transform: (val) => ({
    ...val,
    date: new Date(val.date),
  }),
};
export const useSale: (
  idSale: string
) => [SaleType | undefined, boolean, any] = (idSale) =>
  useObjectVal < SaleType > (database.ref(`sales/${idSale}`), options);
export const useSales: () => [SaleType[] | undefined, boolean, any] = () =>
  useListVals < SaleType > (database.ref('sales'), options);

The transform function might be used for various purposes:

transform: ({ firstName, lastName, someBool, ...val }) => ({
  // Merge in default values, declared elsewhere:
  ...defaultValues,
  // Override them with the actual values
  ...val,
  // Create new fields from existing values
  fullName: `${firstName} ${lastName}`,
  // Ensure a field is a proper boolean instead of truish or falsy:
  someBool: !!someBool,
  // Same goes for any other poorly represented data type
});