I am currently working on an app where I need to restrict access for reading, writing (etc..) a document in a collection. However, I am still able to fetch the data.
Brief explanation of the structure and code:
(I have simplified the code and images for ease of understanding)
This is a representation of the current Firestore structure:

I have a collection of "groups", whereas each group will have members and owners. Every user is defined in the collection of "users" and is assigned a user-ID (the user-IDs are used for assigning users to a group).
Firstly, Let's say you want to fetch all groups (GET /api/groups), all groups given from the API should be all the groups you are a part of. If you are not a part of the group, it should not be returned.
If I'm part of a group I would expect to GET a list of groups; e.g.
[
{groupName: 1, members: ["..."], owners: ["myId"]},
{groupName: 2, members: ["myID"], owners: ["..."]}
]
If I'm not a part of any groups, I would expect an empty list [] or some error..
Next.Js:
In the file pages/api/groups/index.tsx I have created an API handler that fetches all the available groups in the collection "groups":
import { NextApiRequest, NextApiResponse } from 'next';
import db from 'config/db';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const groupsRef = await db.collection('groups');
if (req.method === 'GET') {
const groups = await groupsRef.get();
const groupsData = groups.docs.map((doc) => doc.data());
res.status(200).json(groupsData);
}
if (req.method === 'POST') {
...
}
} catch (err) {
res.status(400).end();
}
}
Firestore Rules
For ease of testing I have created a simple rule that should restrict any READING or writing from the collection "groups":
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /groups/{id} {
allow read, write: if false;
}
}
}
After Publishing, I expected an error or empty list. I however still got the data from groups when fetching the data in e. g. pages/index.tsx:
import React from 'react';
import axios from 'axios';
import useSWR from 'swr';
const fetcher = (url: string) => axios.get(url).then((res) => res.data);
export default function index() {
const { data, error } useSWR('/api/groups', fetcher);
console.log(data);
console.log(error);
if (!data) { ... }
if (error) { ... }
return (<div> ... </div>)
}
Have I misunderstood the purpose of Firestore Rules? Or is there something wrong with the security rules? Why do I still get the data?
[EDIT] (answering Dharmaraj's question):
Can you share import db from 'config/db'; file? Are you using the Admin SDK (that bypasses all the security rules)?
inside /config/db/index.js
import admin from 'firebase-admin';
import serviceAccount from './serviceAccountKey.json';
if (!admin.apps.length) {
try {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
} catch (error) {
console.log('Firebase admin initialization error', error.stack);
}
}
export default admin.firestore();