Search code examples
reactjsgoogle-cloud-firestorefirebase-authenticationreactfire

Firebase v9: Get documents after user auth (with reactfire)


I am using the new Firebase SDK v9 with React (Next.js) and ReactFire.

I want to get a firestore sub-collection by the user auth id:

import { useFirestore, useFirestoreCollectionData, useSigninCheck } from "reactfire";
import { collection } from "firebase/firestore";

export default function TestComponent() {
  /** Get user data from firebase auth */
  const { data: userAuthData } = useSigninCheck();

  /**
   * Get data from firestore
   * Reactfire example: https://github.com/FirebaseExtended/reactfire/blob/main/example/withoutSuspense/Firestore.tsx#L12-L14
   */
  const userRef = collection(useFirestore(), "users", userAuthData?.user?.uid, "my-sub-collection");
  const { data: userFirestoreData } = useFirestoreCollectionData(userRef);

  return <div>TestComponent</div>;
}

The problem is that in the collection() function userAuthData?.user?.uid cannot be null. So tried the following:

import { useFirestore, useFirestoreCollectionData, useSigninCheck } from "reactfire";
import { collection } from "firebase/firestore";

export default function TestComponent() {
  /** Get user data from firebase auth */
  const { data: userAuthData } = useSigninCheck();

  /** Get data from firestore */
  const firestore = useFirestore();
  /** Change here: */
  const userRef = userAuthData?.user?.uid ? collection(firestore, "users", userAuthData.user.uid, "my-sub-collection"): null;
  const { data: userFirestoreData } = useFirestoreCollectionData(userRef);

  return <div>TestComponent</div>;
}

Only if userAuthData?.user?.uid is not false, the collection() function is executed.

But in this attempt the function useFirestoreCollectionData() gives the error:

TS2345: Argument of type 'CollectionReference | null' is not assignable to parameter of type 'Query'.   Type 'null' is not assignable to type 'Query'.`

So, is there a way to wait for the "auth" process and do all the firestore queries afterwards?


Similar to the code above:

import { useFirestore, useFirestoreCollectionData, useSigninCheck } from "reactfire";
import { collection, query, where } from "firebase/firestore";

export default function TestComponent() {
  /** ...Same code from question 1 here... **/

  /** This array is filled by code, which I have omitted for clarity */
  let serverIds: string[] = [];

  const serverRef = collection(useFirestore(), "server");
  const serverQuery = query(serverRef, where("server_id", "in", serverIds));
  const { data: serverData } = useFirestoreCollectionData(serverQuery);

  return <div>TestComponent</div>;
}

Info: In the where() function "server_id" is intentionally not the id of the document but a field.

The array serverIds is empty and will be filled by the firestore request from the first question.

With this approach, how can I make it so that only when the array is filled, so the function useFirestoreCollectionData() will be executed?


Solution

  • I also wanted to do this, but see this issue on github: https://github.com/FirebaseExtended/reactfire/issues/463 which explains that the maintainers don't want to allow this.

    I would suggest to try listening to an empty collection when the user is not signed in, for the sake of one read. Something like:

    const userRef = userAuthData?.user?.uid ? collection(firestore, "users", userAuthData.user.uid, "my-sub-collection"): collection(firestore, "empty");