Hi everyone,
I’m encountering a persistent “Missing or insufficient permissions” error from Firestore when calling a Next.js server action, even though the Firestore Rules Simulator indicates the operation should be allowed. I’m developing within Firebase Studio.
Context:
- App: Next.js 15+ app with React Server Components and Server Actions.
- Database: Firebase Firestore.
- Authentication: Firebase Authentication (Email/Password). Client-side authentication is working correctly (
useAuth
hook confirms user UID). - Problematic Feature: A “My Friends” page that calls a server action (
getFriends
) to fetch the current user’s friends list.
getFriends
Server Action Logic (simplified in src/lib/social.ts
):
// src/lib/social.ts
'use server';
import { db } from '@/lib/firebase'; // Uses Firebase client SDK
import { collection, getDocs, doc, getDoc } from 'firebase/firestore';
export async function getFriends(userId: string): Promise<any[]> {
if (!userId) throw new Error("User ID is required.");
// Log the userId being used for the query
console.log(`[Server Action - getFriends] Attempting to read friends for userId: ${userId}`);
// Path for the friends subcollection
const friendsPath = `userProfiles/${userId}/friends`;
try {
// 1. Read the user's own friends subcollection
const friendsSnapshot = await getDocs(collection(db, friendsPath));
console.log(`[Server Action - getFriends] Successfully read friends subcollection for ${userId}. Count: ${friendsSnapshot.docs.length}`);
// (Logic to then fetch each friend's profile - simplified for brevity)
// ...
return []; // Placeholder
} catch (error: any) {
console.error(`[Server Action - getFriends] Firestore error for path '${friendsPath}':`, error.code, error.message, error);
throw new Error(`Firestore operation failed for ${friendsPath}: ${error.message} (Code: ${error.code})`);
}
}
Firestore Security Rule for the friends subcollection:
// In Firebase Console Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// ... other rules ...
match /userProfiles/{userId}/friends/{friendDocId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
The Problem: When the “My Friends” page calls getFriends
, the server action throws an error: Error: Firestore operation failed for userProfiles/dkpUrB151mQf9W2tqnK9caN4QMX2/friends: Missing or insufficient permissions. (Code: permission-denied)
(The UID dkpUrB151mQf9W2tqnK9caN4QMX2
is the correctly authenticated client-side user’s UID.)
Debugging Steps & Findings:
- Client-Side Authentication: Confirmed the user is authenticated on the client, and the correct UID (
dkpUrB151mQf9W2tqnK9caN4QMX2
) is passed to the server action. - Firebase Project ID: Confirmed the
firebaseConfig
insrc/lib/firebase.ts
uses the correctprojectId
. - Firestore Rules Simulator:
- When simulating a
get
request for path/userProfiles/dkpUrB151mQf9W2tqnK9caN4QMX2/friends/someFriendId
- With “Authenticated” checked, Provider:
password
, Firebase UID:dkpUrB151mQf9W2tqnK9caN4QMX2
- The simulator ALLOWS the read, correctly evaluating
request.auth.uid == userId
to true.
- Extremely Open Rules Test:
- If I change the Firestore rule for reading all documents to
allow read: if true;
, thegetFriends
server action works (and returns “No friends yet!” as expected for an empty list). - This strongly suggests the issue is with how
request.auth
(specificallyrequest.auth.uid
) is being interpreted by the rules engine when the request comes from the server action in my Firebase Studio environment. It seemsrequest.auth.uid
is not matchinguserId
from the path, orrequest.auth
itself is null in that context.
Question:
Given that the simulator confirms the rule logic is sound, why would requests from a Next.js server action (using the Firebase client SDK) within Firebase Studio fail this specific authenticated rule (request.auth.uid == userId
), even though the client is authenticated with that UID?
Is there a specific way authentication context needs to be handled or propagated for server actions when using the Firebase client SDK in an environment like Firebase Studio for Firestore rules to evaluate request.auth
correctly? Or is this a situation where the Firebase Admin SDK is strictly necessary for server-side data fetching that needs to respect user-based rules (by implementing checks in code)?
Any insights or suggestions on how to ensure the request.auth
context is correctly recognized by Firestore rules for these server-side operations in Firebase Studio would be greatly appreciated!
Thanks!