How to correctly fetch user data in Next.js after Firebase Auth login?

Question: How to correctly fetch user data in Next.js after Firebase Auth login?

Hi everyone,

I’m building a daily grid quiz with Next.js and Firebase and I’m running into a classic problem with loading user-specific data.

The Goal: An anonymous user should be able to play the game. When they reload the page, their progress (correctly guessed drivers, number of attempts) should be restored.

The Problem: When I reload the page, all progress is lost. In the developer console, I see the error: FirebaseError: 7 PERMISSION_DENIED: Missing or insufficient permissions.

My Assumption: The error occurs because my app tries to fetch the user’s submissions (their guesses) on the server (during Server-Side Rendering). At that point, the anonymous Firebase login hasn’t completed, so my Firestore rules correctly block the request.

My Firestore rule for submissions is designed to protect private data and looks like this:

match /submissions/{submissionId} {
  // A user can only read their own submissions.
  allow read: if request.auth != null && request.auth.uid == resource.data.userId;
  allow create: if true;
}


The frontend logic causing the error tries to query the submissions on page load:

// This query fails during server-side rendering
const submissionsQuery = query(
  collection(db, "submissions"),
  where("userId", "==", currentUser.uid), // currentUser.uid is 'null' on the server
  where("gridId", "==", todayId)
);


My Question: What is the correct and common pattern in Next.js for fetching user-specific data from Firestore that is protected by security rules?

How can I ensure that the query for submissions is only executed on the client-side (in the browser), and only after the onAuthStateChanged listener from Firebase has confirmed that the anonymous login was successful?

I’m looking for the right pattern (e.g., using useEffect) to avoid this race condition between server-rendering and client-side authentication.

Thanks for your help!

The allow create: if true; statement in your Firestore rules allows documents to be created without a userId, making them unreadable later because your read rule requires matching the userId . This is likely why data seemed to disappear or become inaccessible after a page refresh.

How about updating your firestore.rules to something like this:

// Rules for submissions
match /submissions/{submissionId} {
  // A user can only read, update, or delete their own submissions.
  allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.userId;
  // A user can only create a submission for themselves, 
  // and the new document must contain their userId.
  allow create: if request.auth != null && request.resource.data.userId == request.auth.uid;
}
1 Like