@smart-hook/react-smart-hook-firebase
TypeScript icon, indicating that this package has built-in type declarations

0.0.20 • Public • Published

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.

  1. You can only get value asynchronously, even if it has been cached. (getDocFromCache can only return Promise)
  2. 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>;

Readme

Keywords

none

Package Sidebar

Install

npm i @smart-hook/react-smart-hook-firebase

Weekly Downloads

23

Version

0.0.20

License

MIT

Unpacked Size

104 kB

Total Files

14

Last publish

Collaborators

  • 4kizuki
  • kmashiko
  • norami