Skip to content

Add auth to the manual testing example #54

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
Expand Down
11 changes: 6 additions & 5 deletions manual-emulator-testing/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Manual testing using the Emulator Suite

This directory contains a very basic web app that connects to the
Cloud Firestore emulator. You can read and write data from the database
without affecting production.
Cloud Firestore and Firebase Authentication emulators.

You sign in and read and write data in a completely local environment.

## Setup

Expand All @@ -18,6 +19,6 @@ firebase --project=fakeproject emulators:start
```

Next visit `http://localhost:5000` in your browser and you should see a
_very_ barebones chat app powered by the Cloud Firestore emulator. Try
adding some messages and then click the link at the bottom of the UI to
view the messages in the Emulator UI.
_very_ barebones chat app powered by the Cloud Firestore and Firebase
Authentication emulators. Try adding some messages and then click the link
at the bottom of the UI to view the messages in the Emulator UI.
3 changes: 3 additions & 0 deletions manual-emulator-testing/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
]
},
"emulators": {
"auth": {
"port": 9099
},
"firestore": {
"port": 8080
},
Expand Down
6 changes: 3 additions & 3 deletions manual-emulator-testing/firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /messages/{message} {
// Note: these are extremely basic rules because this sample does not use Firebase Authentication,
// but these rules are NOT appropriate for a production chat app.
allow read;
// Note: these are extremely basic rules but these rules are NOT secure enough
// for a production chat app.
allow read: if request.auth.token.email != null;
allow write: if request.resource.data.keys().hasOnly(['text', 'time'])
}
}
Expand Down
42 changes: 26 additions & 16 deletions manual-emulator-testing/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,40 @@

<!-- Firebase SDKs -->
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.0.2/firebase-firestore.js"></script>
</head>

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

<br />
<div v-else>
<h4>Messages</h4>
<ul>
<li
v-for="(msg, index) in messages"
v-bind:key="index">
{{ msg.text }}
</li>
</ul>

<form>
<input v-model="msgInput" type="text" placeholder="Add a message..." autofocus></textarea>
<button v-on:click.prevent="submit()">Submit</button>
</form>
<form style="padding-top: 12px; padding-bottom: 12px;">
<input v-model="msgInput" type="text" placeholder="Add a message..." autofocus></textarea>
<button v-on:click.prevent="submit()">Submit</button>
</form>
</div>


<br />

<a href="http://localhost:4000/firestore" style="font-size: 9pt;" target="_blank">View data in the Emulator UI</a>
<a href="http://localhost:4000/" style="font-size: 9pt;" target="_blank">View data in the Emulator UI</a>
</div>
<script src="/index.js"></script>
</body>
Expand Down
76 changes: 59 additions & 17 deletions manual-emulator-testing/public/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@
* limitations under the License.
*/

// Initialze Firestore pointing at our test project
const db = firebase
.initializeApp({
projectId: "fakeproject",
})
.firestore();
// Initialze Firebase pointing at our test project
firebase.initializeApp({
projectId: "fakeproject",
apiKey: "fakeApiKey"
});

const db = firebase.firestore();
const auth = firebase.auth();

// Connect Firebase Auth to the local emulator
auth.useEmulator("http://localhost:9099");

// Connect the Firestore SDK to the local emulator
db.settings({
host: "localhost:8080",
ssl: false,
});
db.useEmulator("localhost", 8080);

// Use Vue.js to populate the UI with data
//
Expand All @@ -34,8 +36,11 @@ db.settings({
const app = new Vue({
el: "#app",
data: {
currentUser: null,
messages: [],
msgInput: "",
emailInput: "",
passwordInput: "",
},
methods: {
submit: function () {
Expand All @@ -47,14 +52,51 @@ const app = new Vue({

this.msgInput = "";
},
signUp: async function() {
console.log("Attempting sign up as", this.emailInput);
try {
const user = await auth.createUserWithEmailAndPassword(this.emailInput, this.passwordInput);
this.setUser(user);
} catch (e) {
console.warn(e);
}
},
signIn: async function() {
console.log("Attempting sign in as", this.emailInput);
try {
const user = await auth.signInWithEmailAndPassword(this.emailInput, this.passwordInput);
this.setUser(user);
} catch (e) {
console.warn(e);
}
},
setUser: function (user) {
this.currentUser = user;
if (user != null) {
console.log("Signed in as ", user);

// Listen to the messages collection
db.collection("messages")
.orderBy("time", "asc")
.onSnapshot((snap) => {
console.log("Got data from firestore!");
this.messages = snap.docs.map((doc) => doc.data());
});
}
}
},
computed: {
signedIn: function () {
return this.currentUser !== null;
}
},
created: function () {
// Listen to the messages collection
db.collection("messages")
.orderBy("time", "asc")
.onSnapshot((snap) => {
console.log("Got data from firestore!");
this.messages = snap.docs.map((doc) => doc.data());
});
// Listen to auth state
this.setUser(auth.currentUser);
auth.onAuthStateChanged((user) => {
this.setUser(user);
});


},
});