react-firebase-hooks

repository·master·Indexed 25 days ago

https://github.com/csfrequency/react-firebase-hooks

Lifecycle-aware React hooks for interacting with Firebase services. Version 5.1.1 provides modules for Firebase Authentication, including state monitoring with useAuthState and useIdToken, user registration, social provider sign-ins, and account management. It also includes a Realtime Database module with hooks like useList, useListKeys, useListVals, useObject, and useObjectVal to monitor snapshots and values with built-in loading and error state management.

Tokens
9.4K
Snippets
33
Records
56
Agent score
86%

What's inside react-firebase-hooks

  1. Transform Firebase data with transform options

    master

    Both useListVals and useObjectVal support a transform function in their options object. This allows you to convert raw Firebase data types (like strings or numbers) into application-specific types (like Date objects).

    Usage Notes:

    • The transform function signature is (val: any) => T.
    • It is called once for useObjectVal and once per item for useListVals.
    • The transform function does not receive key or ref values; if you use keyField or refField, those properties are merged into the result after transformation.
    • Performance: If defining the transform function inside a React component, memoize it (e.g., using useCallback) to prevent unnecessary re-renders.

    Example: Converting a string to a Date object

    type SaleType = {
      idSale: string,
      date: Date,
    };
    
    const options = {
      keyField: 'idSale',
      transform: (val) => ({
        ...val,
        date: new Date(val.date),
      }),
    };
    
    // Usage in a custom hook
    export const useSale = (idSale: string) => 
      useObjectVal<SaleType>(database.ref(`sales/${idSale}`), options);
    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);
  2. Transform Firestore data using FirestoreDataConverter

    master

    To transform data as it leaves the Firestore database or to include fields like id and ref in your application state, use the built-in Firebase FirestoreDataConverter.

    Note: This method replaces the transform, idField, and refField options that were used in react-firebase-hooks v4 and earlier. You should implement the converter and apply it to your collection or document reference using .withConverter() before passing it to a hook.

    type Post = {
      author: string,
      id: string,
      ref: DocumentReference<DocumentData>,
      title: string,
    };
    
    const postConverter: FirestoreDataConverter<Post> = {
      toFirestore(post: WithFieldValue<Post>): DocumentData {
        return { author: post.author, title: post.title };
      },
      fromFirestore(
        snapshot: QueryDocumentSnapshot,
        options: SnapshotOptions
      ): Post {
        const data = snapshot.data(options);
        return {
          author: data.author,
          id: snapshot.id,
          ref: snapshot.ref,
          title: data.title,
        };
      },
    };
    
    // Apply the converter to the collection reference
    const ref = collection(firestore, 'posts').withConverter(postConverter);
    
    // Use the converted reference with a hook
    const [data, loading, error] = useCollectionData(ref);
  3. Use Cloud Firestore hooks

    master

    React Firebase Hooks provides convenience listeners for Collections and Documents in Cloud Firestore by wrapping the firestore.onSnapshot(...) method.

    All Firestore hooks can be imported from react-firebase-hooks/firestore.

    There are two main variants for each hook:

    • useX: Subscribes to the underlying Collection or Document and listens for real-time changes.
    • useXOnce: Reads the current value of the Collection or Document once (non-subscribing).

    Each hook provides a complete lifecycle by returning loading and error properties alongside the data.

    import { useCollection } from 'react-firebase-hooks/firestore';
  4. Full example of useToken

    master

    This example demonstrates how to implement the useToken hook within a React component to handle the loading, error, and success states of retrieving a Firebase Cloud Messaging token.

    import { getMessaging } from 'firebase/messaging';
    import { useToken } from 'react-firebase-hooks/messaging';
    
    const MessagingToken = () => {
      const [token, loading, error] = useToken(getMessaging(firebaseApp));
      return (
        <div>
          <p>
            {error && <strong style={{ color: 'red' }}>Error: {JSON.stringify(error)}</strong>}
            {loading && <span>Loading token...</span>}
            {token && <span>Token: {token}</span>}
          </p>
        </div>
      );
    };
  5. Full example of useHttpsCallable

    master

    This example demonstrates how to import getFunctions from the Firebase SDK and useHttpsCallable from react-firebase-hooks/functions to create a component that executes a Cloud Function and handles loading and error states.

    import { getFunctions } from 'firebase/functions';
    import { useHttpsCallable } from 'react-firebase-hooks/functions';
    
    const HttpsCallable = () => {
      const [executeCallable, executing, error] = useHttpsCallable(
        getFunctions(firebaseApp),
        'myHttpsCallable'
      );
      return (
        <div>
          <p>
            {error && <strong>Error: {JSON.stringify(error)}</strong>}
            {executing && <span>Function executing...</span>}
            <button
              onClick={async () => {
                await executeCallable();
                alert('Executed function');
              }}
            >
              Execute callable function
            </button>
          </p>
        </div>
      );
    };
  6. Example: Upload a file

    master

    This example demonstrates how to use useUploadFile to select a file from an input and upload it to a specific path in Firebase Storage with metadata.

    import { getStorage, storageRef } from 'firebase/storage';
    import { useUploadFile } from 'react-firebase-hooks/storage';
    
    const storage = getStorage(firebaseApp);
    
    const UploadFile = () => {
      const [uploadFile, uploading, snapshot, error] = useUploadFile();
      const ref = storageRef(storage, 'file.jpg');
      const [selectedFile, setSelectedFile] = useState<File>();
    
      const upload = async () => {
        if (selectedFile) {
          const result = await uploadFile(ref, selectedFile, {
            contentType: 'image/jpeg'
          });
          alert(`Result: ${JSON.stringify(result)}`);
        }
      }
    
      return (
        <div
          >
          <p>
            {error && <strong>Error: {error.message}</strong>}
            {uploading && <span>Uploading file...</span>}
            {snapshot && <span>Snapshot: {JSON.stringify(snapshot)}</span>}
            {selectedFile && <span>Selected file: {selectedFile.name}</span>}
            <input
              type="file"
              onChange={(e) => {
                const file = e.target.files ? e.target.files[0] : undefined;
                setSelectedFile(file);
              }}
            />
            <button onClick={upload}>Upload file</button>
          </p>
        </div>
      )
    }