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 react-firebase-hooks/database, e.g.
import { useList } from 'react-firebase-hooks/database';List of Realtime Database hooks:
Additional functionality:
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.Referencefor the data you would like to load
Returns:
snapshots: an array ofdatabase.DataSnapshot, orundefinedif no reference is suppliedloading: abooleanto indicate if the data is still being loadederror: AnyErrorreturned by Firebase when trying to load the data, orundefinedif there is no error
import { ref, getDatabase } from 'firebase/database';
import { useList } from 'react-firebase-hooks/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>
);
};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.Referencefor the data you would like to load
Returns:
keys: an array ofstring, orundefinedif no reference is suppliedloading: abooleanto indicate if the data is still being loadederror: AnyErrorreturned by Firebase when trying to load the data, orundefinedif there is no error
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.Referencefor the data you would like to loadoptions: (optional)Objectwith the following parameters:keyField: (optional)stringfield name that should be populated with thedatabase.DataSnapshot.idproperty in the returned values.refField: (optional)stringfield name that should be populated with thedatabase.DataSnapshot.refproperty.transform: (optional) a function that receives the rawdatabase.DataSnapshot.val()for each item in the list to allow manual transformation of the data where required by the application. SeeTransforming databelow.
Returns:
values: an array ofT, orundefinedif no reference is suppliedloading: abooleanto indicate if the data is still being loadederror: AnyErrorreturned by Firebase when trying to load the data, orundefinedif there is no error
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.Referencefor the data you would like to load
Returns:
snapshot: adatabase.DataSnapshot, orundefinedif no reference is suppliedloading: abooleanto indicate if the data is still being loadederror: AnyErrorreturned by Firebase when trying to load the data, orundefinedif there is no error
import { ref, getDatabase } from 'firebase/database';
import { useObject } from 'react-firebase-hooks/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>
);
};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.Referencefor the data you would like to loadoptions: (optional)Objectwith the following parameters:keyField: (optional)stringfield name that should be populated with thedatabase.DataSnapshot.keyproperty in the returned value.refField: (optional)stringfield name that should be populated with thedatabase.DataSnapshot.refproperty.transform: (optional) a function that receives the rawdatabase.DataSnapshot.val()to allow manual transformation of the data where required by the application. SeeTransforming databelow.
Returns:
value: aT, orundefinedif no reference is suppliedloading: abooleanto indicate if the data is still being loadederror: AnyFirebaseErrorreturned by Firebase when trying to load the data, orundefinedif there is no error
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.
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
});