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:
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 ofdatabase.DataSnapshot
, orundefined
if no reference is suppliedloading
: aboolean
to indicate if the data is still being loadederror
: AnyError
returned by Firebase when trying to load the data, orundefined
if there is no error
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>
);
};
const [keys, loading, error] = useListKeys(reference);
As useList
, but this hooks extracts the database.DataSnapshot.key
values, rather than the the database.DataSnapshot
s themselves.
The useListKeys
hook takes the following parameters:
reference
: (optional)database.Reference
for the data you would like to load
Returns:
keys
: an array ofstring
, orundefined
if no reference is suppliedloading
: aboolean
to indicate if the data is still being loadederror
: AnyError
returned by Firebase when trying to load the data, orundefined
if 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.DataSnapshot
s themselves.
The useListVals
hook takes the following parameters:
reference
: (optional)database.Reference
for the data you would like to loadoptions
: (optional)Object
with the following parameters:keyField
: (optional)string
field name that should be populated with thedatabase.DataSnapshot.id
property in the returned values.refField
: (optional)string
field name that should be populated with thedatabase.DataSnapshot.ref
property.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 data
below.
Returns:
values
: an array ofT
, orundefined
if no reference is suppliedloading
: aboolean
to indicate if the data is still being loadederror
: AnyError
returned by Firebase when trying to load the data, orundefined
if 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.Reference
for the data you would like to load
Returns:
snapshot
: adatabase.DataSnapshot
, orundefined
if no reference is suppliedloading
: aboolean
to indicate if the data is still being loadederror
: AnyError
returned by Firebase when trying to load the data, orundefined
if there is no error
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>
);
};
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 loadoptions
: (optional)Object
with the following parameters:keyField
: (optional)string
field name that should be populated with thedatabase.DataSnapshot.key
property in the returned value.refField
: (optional)string
field name that should be populated with thedatabase.DataSnapshot.ref
property.transform
: (optional) a function that receives the rawdatabase.DataSnapshot.val()
to allow manual transformation of the data where required by the application. SeeTransforming data
below.
Returns:
value
: aT
, orundefined
if no reference is suppliedloading
: aboolean
to indicate if the data is still being loadederror
: AnyFirebaseError
returned by Firebase when trying to load the data, orundefined
if 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
});