Skip to content

Commit 681669b

Browse files
committed
phase 1 of tutorial
1 parent 84d0c80 commit 681669b

4 files changed

Lines changed: 54 additions & 146 deletions

File tree

TUTORIAL.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,47 @@ Now we're ready to actually run the tests:
1818
```
1919
firebase emulators:exec "npm test"
2020
```
21+
22+
If all goes well, you should see
23+
```
24+
> mocha
25+
26+
✓ a random user can write a random document
27+
```
28+
29+
## Securing your data
30+
31+
Open `firestore.rules` and you'll see that your rules are currently allowing
32+
all reads and writes. Let's start by locking down the database.
33+
34+
Set your security rules to
35+
```
36+
service cloud.firestore {
37+
match /databases/{db}/documents {
38+
match /{doc=**} {
39+
allow read, write: if false;
40+
}
41+
}
42+
}
43+
```
44+
45+
Re-run your test and you should see
46+
47+
```
48+
> mocha
49+
50+
51+
52+
1) a random user can write a random document
53+
54+
0 passing (787ms)
55+
1 failing
56+
57+
1) a random user can write a random document:
58+
FirebaseError: 7 PERMISSION_DENIED:
59+
false for 'create' @ L4
60+
```
61+
62+
which verifies that our rules are no longer allowing random users to write to
63+
random documents. Let's update the test. Open `test/test.js` and change
64+
`firebase.assertSucceeds` to `firebase.assertFails`.

firestore.rules

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
service cloud.firestore {
2-
match /databases/{database}/documents {
3-
match /users/{userId} {
4-
allow read;
5-
allow create: if request.auth.uid == userId && request.resource.data.createdAt == request.time;
6-
}
7-
match /rooms/{roomId} {
8-
allow read;
9-
// If you create a room, you must set yourself as the owner.
10-
allow create: if request.resource.data.owner == request.auth.uid;
11-
// Only the room owner is allowed to modify it.
12-
allow update: if resource.data.owner == request.auth.uid;
2+
match /databases/{db}/documents {
3+
match /{doc=**} {
4+
allow read, write: if true;
135
}
146
}
157
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Cloud Firestore emulator testing",
55
"scripts": {
66
"format": "prettier --write **/*.js",
7-
"test": "mocha"
7+
"test": "mocha --exit"
88
},
99
"devDependencies": {
1010
"@firebase/testing": "^0.10.1",

test/test.js

Lines changed: 6 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -1,138 +1,10 @@
11
const firebase = require("@firebase/testing");
22
const fs = require("fs");
3+
const projectId = "rules-codelab";
34

4-
/*
5-
* ============
6-
* Setup
7-
* ============
8-
*/
9-
const projectId = "firestore-emulator-example";
10-
const coverageUrl = `http://localhost:8080/emulator/v1/projects/${projectId}:ruleCoverage.html`;
11-
12-
const rules = fs.readFileSync("firestore.rules", "utf8");
13-
14-
/**
15-
* Creates a new app with authentication data matching the input.
16-
*
17-
* @param {object} auth the object to use for authentication (typically {uid: some-uid})
18-
* @return {object} the app.
19-
*/
20-
function authedApp(auth) {
21-
return firebase
22-
.initializeTestApp({ projectId, auth })
23-
.firestore();
24-
}
25-
26-
/*
27-
* ============
28-
* Test Cases
29-
* ============
30-
*/
31-
beforeEach(async () => {
32-
// Clear the database between tests
33-
await firebase.clearFirestoreData({ projectId });
34-
});
35-
36-
before(async () => {
37-
await firebase.loadFirestoreRules({ projectId, rules });
38-
});
39-
40-
after(async () => {
41-
await Promise.all(firebase.apps().map(app => app.delete()));
42-
console.log(`View rule coverage information at ${coverageUrl}\n`);
43-
});
44-
45-
describe("My app", () => {
46-
it("require users to log in before creating a profile", async () => {
47-
const db = authedApp(null);
48-
const profile = db.collection("users").doc("alice");
49-
await firebase.assertFails(profile.set({ birthday: "January 1" }));
50-
});
51-
52-
it("should enforce the createdAt date in user profiles", async () => {
53-
const db = authedApp({ uid: "alice" });
54-
const profile = db.collection("users").doc("alice");
55-
await firebase.assertFails(profile.set({ birthday: "January 1" }));
56-
await firebase.assertSucceeds(
57-
profile.set({
58-
birthday: "January 1",
59-
createdAt: firebase.firestore.FieldValue.serverTimestamp()
60-
})
61-
);
62-
});
63-
64-
it("should only let users create their own profile", async () => {
65-
const db = authedApp({ uid: "alice" });
66-
await firebase.assertSucceeds(
67-
db
68-
.collection("users")
69-
.doc("alice")
70-
.set({
71-
birthday: "January 1",
72-
createdAt: firebase.firestore.FieldValue.serverTimestamp()
73-
})
74-
);
75-
await firebase.assertFails(
76-
db
77-
.collection("users")
78-
.doc("bob")
79-
.set({
80-
birthday: "January 1",
81-
createdAt: firebase.firestore.FieldValue.serverTimestamp()
82-
})
83-
);
84-
});
85-
86-
it("should let anyone read any profile", async () => {
87-
const db = authedApp(null);
88-
const profile = db.collection("users").doc("alice");
89-
await firebase.assertSucceeds(profile.get());
90-
});
91-
92-
it("should let anyone create a room", async () => {
93-
const db = authedApp({ uid: "alice" });
94-
const room = db.collection("rooms").doc("firebase");
95-
await firebase.assertSucceeds(
96-
room.set({
97-
owner: "alice",
98-
topic: "All Things Firebase"
99-
})
100-
);
101-
});
102-
103-
it("should force people to name themselves as room owner when creating a room", async () => {
104-
const db = authedApp({ uid: "alice" });
105-
const room = db.collection("rooms").doc("firebase");
106-
await firebase.assertFails(
107-
room.set({
108-
owner: "scott",
109-
topic: "Firebase Rocks!"
110-
})
111-
);
112-
});
113-
114-
it("should not let one user steal a room from another user", async () => {
115-
const alice = authedApp({ uid: "alice" });
116-
const bob = authedApp({ uid: "bob" });
117-
118-
await firebase.assertSucceeds(
119-
bob
120-
.collection("rooms")
121-
.doc("snow")
122-
.set({
123-
owner: "bob",
124-
topic: "All Things Snowboarding"
125-
})
126-
);
127-
128-
await firebase.assertFails(
129-
alice
130-
.collection("rooms")
131-
.doc("snow")
132-
.set({
133-
owner: "alice",
134-
topic: "skiing > snowboarding"
135-
})
136-
);
137-
});
5+
it("a random user can write a random document", async () => {
6+
const db = firebase.initializeTestApp({ projectId, auth: null }).firestore();
7+
await firebase.assertSucceeds(
8+
db.collection("random-collection").doc("random-document").set({ hello: "world" })
9+
);
13810
});

0 commit comments

Comments
 (0)