Skip to content

Commit b00f995

Browse files
authored
Merge pull request #201 from samtstern/database-docs
Add more information to database README
2 parents 405c4dc + 06ccef2 commit b00f995

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

database/README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,104 @@ Result
1818
-----------
1919
<img src="app/src/screen.png" height="534" width="300"/>
2020

21+
22+
Data Model
23+
-----------
24+
This quickstart demonstrates a simple data model for a social application.
25+
While this data model uses some of the Firebase best practices, it has some
26+
known tradeoffs made for simplicity that would not scale to very large numbers
27+
of users.
28+
29+
The database has four "root" nodes:
30+
31+
* `users` - a list of `User` objects, keyed by user ID. So
32+
`/users/<ID>/email` is the email address of the user with id=`<ID>`.
33+
* `posts` - a list of `Post` objects, keyed by randomly generated push ID.
34+
Each `Post` contains the `uid` and `author` properties to determine the
35+
identity of the author without a JOIN-style query.
36+
* Posts contain a `stars` property which is a `Map` of user IDs to boolean
37+
values. If `/posts/<POST-ID>/stars/<USER-ID>` is `true`, this means
38+
the user with ID `<USER-ID>` has starred the post with ID `<POST-ID>`.
39+
This data nesting makes it easy to tell if a specific user has already
40+
starred a specific post, but would not scale to large numbers of stars
41+
per post as it would make loading the Post data more expensive.
42+
* `user-posts` - a list of lists of posts. `/user-posts/<USER-ID>` is a list
43+
of all posts made by a specific user, keyed by the same push ID used in
44+
the `posts` tree. This makes it easy to query "all posts by a specific
45+
user" without filtering through all Post objects.
46+
* `post-comments` - comments on a particular posts, where
47+
`/post-comments/<POST-ID>` is a list of all comments on post with id
48+
`<POST-ID>`. Each comment has a randomly generated push key. By keeping
49+
this data in its own tree rather than nesting it under `posts`, we make it
50+
possible to load a post without loading all comments while still
51+
having a known path to access all comments for a particular post.
52+
53+
Database Rules
54+
---------------
55+
Below are some samples rules that limit access and validate data:
56+
57+
```javascript
58+
{
59+
"rules": {
60+
// User profiles are only readable/writable by the user who owns it
61+
"users": {
62+
"$UID": {
63+
".read": "auth.uid == $UID",
64+
".write": "auth.uid == $UID"
65+
}
66+
},
67+
68+
// Posts can be read by anyone but only written by logged-in users.
69+
"posts": {
70+
".read": true,
71+
".write": "auth.uid != null",
72+
73+
"$POSTID": {
74+
// UID must matched logged in user and is fixed once set
75+
"uid": {
76+
".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
77+
},
78+
79+
// User can only update own stars
80+
"stars": {
81+
"$UID": {
82+
".validate": "auth.uid == $UID"
83+
}
84+
}
85+
}
86+
},
87+
88+
// User posts can be read by anyone but only written by the user that owns it,
89+
// and with a matching UID
90+
"user-posts": {
91+
".read": true,
92+
93+
"$UID": {
94+
".write": "auth.uid == $UID",
95+
".validate": "data.exists() || newData.child('uid').val() == auth.uid"
96+
}
97+
},
98+
99+
100+
// Comments can be read by anyone but only written by a logged in user
101+
"post-comments": {
102+
".read": true,
103+
".write": "auth.uid != null",
104+
105+
"$POSTID": {
106+
"$COMMENTID": {
107+
// UID must matched logged in user and is fixed once set
108+
"uid": {
109+
".validate": "(data.exists() && data.val() == newData.val()) || newData.val() == auth.uid"
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}
116+
```
117+
118+
21119
Support
22120
-------
23121

0 commit comments

Comments
 (0)