diff --git a/firebase.json b/firebase.json index f4771f1d..f4ae8a93 100644 --- a/firebase.json +++ b/firebase.json @@ -1,5 +1,8 @@ { "emulators": { + "auth": { + "port": 9099 + }, "functions": { "port": 5001 }, diff --git a/manual-emulator-testing/README.md b/manual-emulator-testing/README.md index 67cf6abf..51ae1ba7 100644 --- a/manual-emulator-testing/README.md +++ b/manual-emulator-testing/README.md @@ -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 @@ -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. diff --git a/manual-emulator-testing/firebase.json b/manual-emulator-testing/firebase.json index 4aa5efc7..ad8625cf 100644 --- a/manual-emulator-testing/firebase.json +++ b/manual-emulator-testing/firebase.json @@ -18,6 +18,9 @@ ] }, "emulators": { + "auth": { + "port": 9099 + }, "firestore": { "port": 8080 }, diff --git a/manual-emulator-testing/firestore.rules b/manual-emulator-testing/firestore.rules index 336fdfc4..8bcb0356 100644 --- a/manual-emulator-testing/firestore.rules +++ b/manual-emulator-testing/firestore.rules @@ -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']) } } diff --git a/manual-emulator-testing/public/index.html b/manual-emulator-testing/public/index.html index 137c8648..83d57e0d 100644 --- a/manual-emulator-testing/public/index.html +++ b/manual-emulator-testing/public/index.html @@ -24,30 +24,40 @@ +
-

Messages

- +
+

Sign In

+
+ + + + +
+
-
+
+

Messages

+ -
- - -
+
+ + +
+
+ -
- - View data in the Emulator UI + View data in the Emulator UI
diff --git a/manual-emulator-testing/public/index.js b/manual-emulator-testing/public/index.js index cd3faa79..3efbde32 100644 --- a/manual-emulator-testing/public/index.js +++ b/manual-emulator-testing/public/index.js @@ -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 // @@ -34,8 +36,11 @@ db.settings({ const app = new Vue({ el: "#app", data: { + currentUser: null, messages: [], msgInput: "", + emailInput: "", + passwordInput: "", }, methods: { submit: function () { @@ -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); + }); + + }, });