Skip to content

Commit 76e0c4d

Browse files
authored
Add Firestore Rules to init prompt (#9207)
1 parent a1fa51d commit 76e0c4d

File tree

6 files changed

+86
-3
lines changed

6 files changed

+86
-3
lines changed

firebase.json

Whitespace-only changes.

src/mcp/resources/guides/init_auth.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ export const init_auth = resource(
2424
2525
**Implementation:**
2626
- Create sign-up and login pages using Firebase Authentication
27-
- Update Firestore security rules and deploy them to ensure only authenticated users can access their own data
28-
- Handle security rule updates automatically (do not ask developers to go to console)
2927
3028
**Testing & Deployment:**
3129
- Test the complete sign-up and sign-in flow to verify authentication functionality

src/mcp/resources/guides/init_backend.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ export const init_backend = resource(
2222
The user will likely need to setup Firestore, Authentication, and Hosting. Read the following guides in order. Do not run the app until you have completed all 3 guides.
2323
1. [Firestore](firebase://guides/init/firestore): read this to setup Firestore database
2424
2. [Authentication](firebase://guides/init/auth): read this to setup Firebase Authentication to support multi-user apps
25-
3. [Hosting](firebase://guides/init/hosting): read this if the user would like to deploy to Firebase Hosting
25+
3. [Firestore Rules](firebase://guides/init/firestore_rules): read this to setup the \`firestore.rules\` file for securing your database
26+
4. [Hosting](firebase://guides/init/hosting): read this if the user would like to deploy to Firebase Hosting
2627
2728
**firebase.json**
2829
The firebase.json file is used to deploy Firebase products with the firebase deploy command.

src/mcp/resources/guides/init_firestore.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const init_firestore = resource(
88
description: "guides the coding agent through configuring Firestore in the current project",
99
},
1010
async (uri) => {
11+
const date = getTomorrowDate();
1112
return {
1213
contents: [
1314
{
@@ -18,6 +19,7 @@ export const init_firestore = resource(
1819
**Database Setup:**
1920
- Configure Firebase Firestore as the primary database for the application
2021
- Implement client code for basic CRUD operations using the Firestore SDK
22+
- Write the default \`firestore.rules\` file (see below)
2123
- Run \`firebase deploy --only firestore\` to provision the database automatically
2224
- Use production environment directly (avoid emulator for initial setup)
2325
@@ -45,9 +47,31 @@ export const init_firestore = resource(
4547
- **Authentication**: Recommend implementing Firebase Authentication if the application handles sensitive user data or has open security rules
4648
- **User Management**: Implement user sign-up and login features with Firebase Authentication to establish proper data validation and access controls
4749
- **Security Rules**: Configure user-based security rules based on your application's specific requirements
50+
51+
### Default \`firestore.rules\` file:
52+
53+
\`\`\`
54+
// Allow reads and writes to all documents for authenticated users.
55+
// This rule will only be valid until tomorrow.
56+
rules_version = '2';
57+
service cloud.firestore {
58+
match /databases/{database}/documents {
59+
match /{document=**} {
60+
allow read, write: if request.auth != null && request.time < timestamp.date(${date.year}, ${date.month}, ${date.day});
61+
}
62+
}
63+
}
64+
\`\`\`
4865
`.trim(),
4966
},
5067
],
5168
};
5269
},
5370
);
71+
72+
function getTomorrowDate() {
73+
const tomorrow = new Date();
74+
tomorrow.setDate(tomorrow.getDate() + 1);
75+
// Month is 0-indexed, so add 1
76+
return { year: tomorrow.getFullYear(), month: tomorrow.getMonth() + 1, day: tomorrow.getDate() };
77+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { resource } from "../../resource";
2+
3+
export const init_firestore_rules = resource(
4+
{
5+
uri: "firebase://guides/init/firestore_rules",
6+
name: "firestore_rules_init_guide",
7+
title: "Firestore Rules Init Guide",
8+
description:
9+
"guides the coding agent through setting up Firestore security rules in the project",
10+
},
11+
async (uri, { config }) => {
12+
return {
13+
contents: [
14+
{
15+
uri,
16+
type: "text",
17+
text: `
18+
# Firestore Rules
19+
This guide walks you through updating the Firestore security rules and deploying them to ensure only authenticated users can access their own data.
20+
21+
Contents of the user's current \`firestore.rules\` file:
22+
23+
\`\`\`
24+
${config.readProjectFile("firestore.rules", { fallback: "<FILE DOES NOT EXIST>" })}
25+
\`\`\`
26+
27+
1. Create the personalData and publicData security rules (seen below). If they have existing \`firestore.rules\`, integrate these with the user's existing rules.
28+
2. Validate & fix the security rules using the \`validate_rules\` tool. Only continue to the next step when the \`validate_rules\` tool succeeds
29+
3. Update queries in the user's app to use the updated security rules
30+
4. Print the contents of the \`firestore.rules\` file. Ask the user for permission to deploy the rules. Do not continue until the user confirms. Deploy the security rules using \`firebase deploy --only firestore\` in the terminal. Do not tell the user to go to the console to deploy rules as this command will do it automatically.
31+
32+
For database entities that neatly fall into the "personal" and "public categories, you can use the personalData and publicData rules. Use the following firestore.rules file, and add a comment above 'personalData' and 'publicData' to note what entities apply to each rule.
33+
34+
\`\`\`
35+
rules_version = '2';
36+
37+
service cloud.firestore {
38+
match /databases/{database}/documents {
39+
match /personalData/{appId}/users/{uid}/{collectionName}/{docId} {
40+
allow get: if uid == request.auth.uid;
41+
allow list: if uid == request.auth.uid && request.query.limit <= 100;
42+
allow write: if uid == request.auth.uid;
43+
}
44+
45+
match /publicData/{appId}/{collectionName}/{docId} {
46+
allow get: if true;
47+
allow list: request.query.limit <= 100;
48+
allow write: if true;
49+
}
50+
}
51+
}
52+
\`\`\`
53+
`.trim(),
54+
},
55+
],
56+
};
57+
},
58+
);

src/mcp/resources/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { init_auth } from "./guides/init_auth";
66
import { init_backend } from "./guides/init_backend";
77
import { init_data_connect } from "./guides/init_data_connect";
88
import { init_firestore } from "./guides/init_firestore";
9+
import { init_firestore_rules } from "./guides/init_firestore_rules";
910
import { init_hosting } from "./guides/init_hosting";
1011
import { init_rtdb } from "./guides/init_rtdb";
1112
import { ServerResource, ServerResourceTemplate } from "../resource";
@@ -15,6 +16,7 @@ export const resources = [
1516
init_ai,
1617
init_data_connect,
1718
init_firestore,
19+
init_firestore_rules,
1820
init_rtdb,
1921
init_auth,
2022
init_hosting,

0 commit comments

Comments
 (0)