@smart-hook/react-smart-hook-firebase
v0.0.20
Published
firebase hooks with high performance
Downloads
27
Readme
Overview
React hook for Firebase based on react-hook-retention-cache
.
Difference from react-firebase-hook and plain firebase.
Firebase has an original excellent caching mechanism. In an example of firestore, if you have effective onSnapshot subscription, you can use a cached value via getDocFromCache
, getDoc
or other onSnapshot
subscriptions. But this mechanism has a severe limitation.
- You can only get value asynchronously, even if it has been cached. (
getDocFromCache
can only return Promise) - If a React component subscribes firestore resource and unsubscribe in
unmount
, a cache of a value is also released. And next page cannot use cache. This behaviour cannot be changes at least you use react-firebase-react-hook.
This package resolve these problems with smart caching mechanism privided by react-hook-retention-cache
.
How to handle data model.
In Firestore + TypeScript project, how to handle data model of doc / collection is troublesome problem. One of a smart strategy is to use a model dependent hooks. This strategy is also compatible with caching.
All functions of this package has form of create***Hook(callback)
and generate model dependent hooks. This is very suitable for a modern TypeScript project.
Destructive Change in v0.0.17
- The sequence of parameters passed to createIdTokenHook has been changed.
Destructive Change in v0.0.15
- Hooks generated by createDocumentHook / createQueryHook has become to accept params of undefined / null.
- By this reason, they has become not to accept refGenerator with no params (i.e. () => D ).
- To cover this old use case, new createFixedQueryHook / createFixedDocumentHook has been introduced.
Example
// Doc
export const useClientDoc = createDocumentHook((id: string) =>
doc(clientCollection, id)
);
/* (params: string | undefined) => {
snapshot?: DocumentSnapshot<D>;
error?: FirestoreError;
data?: D;
ref?: DocumentReference<D>;
loading?: boolean;
} */
export const useDefaultClientDoc = createFixedQueryHook(() =>
doc(clientCollection, "default")
);
/* () => {
snapshot?: DocumentSnapshot<D>;
error?: FirestoreError;
data?: D;
ref: DocumentReference<D>;
loading?: boolean;
} */
// Query
export const useCouponList = createFixedQueryHook(() => {
return query(userCollection, orderBy("createdAt", "desc").withConverter(withIdConverter<D>()));
});
/* () =>{
snapshot?: QuerySnapshot<D>;
error?: FirestoreError;
list?: D[];
ref: Query<D>;
loading?: boolean;
} */
const useIdTokenResult = createIdTokenHook(auth, (claims, user) => {
return {
role: claims?.role as string | undefined,
uid: claims?.sub as string | undefined,
email: claims?.email as string | undefined,
};
});
/* () => {
error?: Error;
data?: {
role: string | undefined;
uid: string | undefined;
email: string | undefined;
};
} */
API
firestore doc
declare type DocumentResult<D> = {
snapshot?: DocumentSnapshot<D>;
error?: FirestoreError;
data?: D;
ref: DocumentReference<D>;
loading?: boolean;
};
declare type UseDocumentOption = {
withData?: boolean;
retentionTime?: number | undefined;
};
declare function createDocumentHook<D, P>(refGenerator: (params: P) => DocumentReference<D>, { withData, retentionTime }?: UseDocumentOption): (params: P | null | undefined) => emptyObject | DocumentResult<D>;
declare function createFixedDocumentHook<D>(refGenerator: () => DocumentReference<D>, { withData, retentionTime }?: UseDocumentOption): () => emptyObject | DocumentResult<D>;
declare const createDocumentRefHook: ({ withData, retentionTime }?: UseDocumentOption) => <D>(params: DocumentReference<D>) => DocumentResult<D>;
firestore query (including collection)
declare type QueryResult<D> = {
snapshot?: QuerySnapshot<D>;
error?: FirestoreError;
list?: D[];
ref: Query<D>;
loading?: boolean;
};
declare type UseQueryOption = {
withData?: boolean;
retentionTime?: number | undefined;
};
declare const createQueryHook: <D, P>(refGenerator: (params: P) => Query<D>, { withData, retentionTime }?: UseQueryOption) => (params: P | null | undefined) => emptyObject | QueryResult<D>;
declare const createFixedQueryHook: <D>(refGenerator: () => Query<D>, { withData, retentionTime }?: UseQueryOption) => () => emptyObject | QueryResult<D>;
declare const createQueryRefHook: (options?: UseQueryOption) => <D>(params: Query<D>) => QueryResult<D>;
firebase authentication
declare type IdTokenResult<D> = {
error?: Error;
data?: D;
};
declare const createIdTokenHook: <D>(auth: Auth, projector: (user?: User | undefined, claims?: ParsedToken | undefined, ) => D, { retentionTime }?: {
retentionTime: number | undefined;
}) => () => IdTokenResult<D>;
declare type AuthResult<D> = {
error?: Error;
data?: D;
};
declare const createAuthHook: <D>(auth: Auth, projector: (user?: User | undefined) => D, { retentionTime }?: {
retentionTime: number | undefined;
}) => () => AuthResult<D>;