Skip to content

Commit b01f555

Browse files
authored
Add auth to the manual testing example (#54)
1 parent 51aa115 commit b01f555

File tree

6 files changed

+100
-41
lines changed

6 files changed

+100
-41
lines changed

firebase.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"emulators": {
3+
"auth": {
4+
"port": 9099
5+
},
36
"functions": {
47
"port": 5001
58
},

manual-emulator-testing/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Manual testing using the Emulator Suite
22

33
This directory contains a very basic web app that connects to the
4-
Cloud Firestore emulator. You can read and write data from the database
5-
without affecting production.
4+
Cloud Firestore and Firebase Authentication emulators.
5+
6+
You sign in and read and write data in a completely local environment.
67

78
## Setup
89

@@ -18,6 +19,6 @@ firebase --project=fakeproject emulators:start
1819
```
1920

2021
Next visit `http://localhost:5000` in your browser and you should see a
21-
_very_ barebones chat app powered by the Cloud Firestore emulator. Try
22-
adding some messages and then click the link at the bottom of the UI to
23-
view the messages in the Emulator UI.
22+
_very_ barebones chat app powered by the Cloud Firestore and Firebase
23+
Authentication emulators. Try adding some messages and then click the link
24+
at the bottom of the UI to view the messages in the Emulator UI.

manual-emulator-testing/firebase.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
]
1919
},
2020
"emulators": {
21+
"auth": {
22+
"port": 9099
23+
},
2124
"firestore": {
2225
"port": 8080
2326
},

manual-emulator-testing/firestore.rules

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ rules_version = '2';
22
service cloud.firestore {
33
match /databases/{database}/documents {
44
match /messages/{message} {
5-
// Note: these are extremely basic rules because this sample does not use Firebase Authentication,
6-
// but these rules are NOT appropriate for a production chat app.
7-
allow read;
5+
// Note: these are extremely basic rules but these rules are NOT secure enough
6+
// for a production chat app.
7+
allow read: if request.auth.token.email != null;
88
allow write: if request.resource.data.keys().hasOnly(['text', 'time'])
99
}
1010
}

manual-emulator-testing/public/index.html

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,40 @@
2424

2525
<!-- Firebase SDKs -->
2626
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-app.js"></script>
27+
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-auth.js"></script>
2728
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-firestore.js"></script>
2829
</head>
2930

3031
<body>
3132
<div id="app">
32-
<h4>Messages</h4>
33-
<ul>
34-
<li
35-
v-for="(msg, index) in messages"
36-
v-bind:key="index">
37-
{{ msg.text }}
38-
</li>
39-
</ul>
33+
<div v-if="!signedIn">
34+
<h4>Sign In</h4>
35+
<form style="padding-top: 12px; padding-bottom: 12px;">
36+
<input v-model="emailInput" type="email" placeholder="Email" autofocus></textarea>
37+
<input v-model="passwordInput" type="password" placeholder="Password"></textarea>
38+
<button v-on:click.prevent="signIn()">Sign In</button>
39+
<button v-on:click.prevent="signUp()">Sign Up</button>
40+
</form>
41+
</div>
4042

41-
<br />
43+
<div v-else>
44+
<h4>Messages</h4>
45+
<ul>
46+
<li
47+
v-for="(msg, index) in messages"
48+
v-bind:key="index">
49+
{{ msg.text }}
50+
</li>
51+
</ul>
4252

43-
<form>
44-
<input v-model="msgInput" type="text" placeholder="Add a message..." autofocus></textarea>
45-
<button v-on:click.prevent="submit()">Submit</button>
46-
</form>
53+
<form style="padding-top: 12px; padding-bottom: 12px;">
54+
<input v-model="msgInput" type="text" placeholder="Add a message..." autofocus></textarea>
55+
<button v-on:click.prevent="submit()">Submit</button>
56+
</form>
57+
</div>
58+
4759

48-
<br />
49-
50-
<a href="http://localhost:4000/firestore" style="font-size: 9pt;" target="_blank">View data in the Emulator UI</a>
60+
<a href="http://localhost:4000/" style="font-size: 9pt;" target="_blank">View data in the Emulator UI</a>
5161
</div>
5262
<script src="/index.js"></script>
5363
</body>

manual-emulator-testing/public/index.js

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,20 @@
1414
* limitations under the License.
1515
*/
1616

17-
// Initialze Firestore pointing at our test project
18-
const db = firebase
19-
.initializeApp({
20-
projectId: "fakeproject",
21-
})
22-
.firestore();
17+
// Initialze Firebase pointing at our test project
18+
firebase.initializeApp({
19+
projectId: "fakeproject",
20+
apiKey: "fakeApiKey"
21+
});
22+
23+
const db = firebase.firestore();
24+
const auth = firebase.auth();
25+
26+
// Connect Firebase Auth to the local emulator
27+
auth.useEmulator("http://localhost:9099");
2328

2429
// Connect the Firestore SDK to the local emulator
25-
db.settings({
26-
host: "localhost:8080",
27-
ssl: false,
28-
});
30+
db.useEmulator("localhost", 8080);
2931

3032
// Use Vue.js to populate the UI with data
3133
//
@@ -34,8 +36,11 @@ db.settings({
3436
const app = new Vue({
3537
el: "#app",
3638
data: {
39+
currentUser: null,
3740
messages: [],
3841
msgInput: "",
42+
emailInput: "",
43+
passwordInput: "",
3944
},
4045
methods: {
4146
submit: function () {
@@ -47,14 +52,51 @@ const app = new Vue({
4752

4853
this.msgInput = "";
4954
},
55+
signUp: async function() {
56+
console.log("Attempting sign up as", this.emailInput);
57+
try {
58+
const user = await auth.createUserWithEmailAndPassword(this.emailInput, this.passwordInput);
59+
this.setUser(user);
60+
} catch (e) {
61+
console.warn(e);
62+
}
63+
},
64+
signIn: async function() {
65+
console.log("Attempting sign in as", this.emailInput);
66+
try {
67+
const user = await auth.signInWithEmailAndPassword(this.emailInput, this.passwordInput);
68+
this.setUser(user);
69+
} catch (e) {
70+
console.warn(e);
71+
}
72+
},
73+
setUser: function (user) {
74+
this.currentUser = user;
75+
if (user != null) {
76+
console.log("Signed in as ", user);
77+
78+
// Listen to the messages collection
79+
db.collection("messages")
80+
.orderBy("time", "asc")
81+
.onSnapshot((snap) => {
82+
console.log("Got data from firestore!");
83+
this.messages = snap.docs.map((doc) => doc.data());
84+
});
85+
}
86+
}
87+
},
88+
computed: {
89+
signedIn: function () {
90+
return this.currentUser !== null;
91+
}
5092
},
5193
created: function () {
52-
// Listen to the messages collection
53-
db.collection("messages")
54-
.orderBy("time", "asc")
55-
.onSnapshot((snap) => {
56-
console.log("Got data from firestore!");
57-
this.messages = snap.docs.map((doc) => doc.data());
58-
});
94+
// Listen to auth state
95+
this.setUser(auth.currentUser);
96+
auth.onAuthStateChanged((user) => {
97+
this.setUser(user);
98+
});
99+
100+
59101
},
60102
});

0 commit comments

Comments
 (0)