Get to know Firebase for web Stay organized with collections Save and categorize content based on your preferences.
1. Overview
In this codelab, you'll learn some of the basics ofFirebase to create interactive web applications. You'll build an event RSVP and guestbook chat app using several Firebase products.

What you'll learn
- Authenticate users with Firebase Authentication and FirebaseUI.
- Sync data using Cloud Firestore.
- Write Firebase Security Rules to secure a database.
What you'll need
- A browser of your choice, such as Chrome.
- Access tostackblitz.com (no account or sign-in necessary).
- A Google account, like a gmail account. We recommend the email account that you already use for your GitHub account. This allows you to use advanced features in StackBlitz.
- The codelab's sample code. See the next step for how to get the code.
2. Get the starting code
In this codelab, you build an app usingStackBlitz, an online editor that has several Firebase workflows integrated into it. Stackblitz requires no software installation or special StackBlitz account.
StackBlitz lets you share projects with others. Other people who have your StackBlitz project URL can see your code and fork your project, but they can't edit your StackBlitz project.
- Go to this URL for the starting code:https://stackblitz.com/edit/firebase-gtk-web-start
- At the top of the StackBlitz page, clickFork:

You now have a copy of the starting code as your own StackBlitz project, which has a unique name, along with a unique URL. All of your files and changes are saved in this StackBlitz project.
Just in case you happen to get off track, there are StackBlitz links at various checkpoints in this codelab, updated with all of the code added up to that point.
Make sure that you do two things at these checkpoints:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console (more on that later in the codelab).
3. Edit event information
The starting materials for this codelab provide some structure for the web app, including some stylesheets and a couple of HTML containers for the app. Later in this codelab, you'll hook these containers up to Firebase.
To get started, let's get a bit more familiar with the StackBlitz interface.
- In StackBlitz, open the
index.htmlfile. - Locate
event-details-containeranddescription-container, then try editing some event details.
As you edit the text, the automatic page reload in StackBlitz displays the new event details. Cool, yeah?
<!-- ... --><div> <img src="..." /> <section> <h1>Firebase Meetup</h1> <p><i>calendar_today</i> October 30</p> <p><i>location_city</i> San Francisco</p> </section> <hr> <section></section> <section> <h2>What we'll be doing</h2> <p>Join us for a day full of Firebase Workshops and Pizza!</p> </section></div><!-- ... -->The preview of your app should look something like this:
App preview

4. Create and set up a Firebase project
Displaying the event information is great for your guests, but just showing the events isn't very useful for anybody. Let's add some dynamic functionality to this app. For this, you'll need to hook Firebase up to your app. To get started with Firebase, you'll need to create and set up a Firebase project.
Create a Firebase project
- Sign into theFirebase console using your Google Account.
- Click the button to create a new project, and then enter a project name (for example,
Firebase-Web-Codelab). - ClickContinue.
- If prompted, review and accept theFirebase terms, and then clickContinue.
- (Optional) Enable AI assistance in the Firebase console (called "Gemini in Firebase").
- For this codelab, you donot need Google Analytics, sotoggle off the Google Analytics option.
- ClickCreate project, wait for your project to provision, and then clickContinue.
To learn more about Firebase projects, seeUnderstand Firebase projects.
Enable and set up Firebase products in the console
The app that you're building uses several Firebase products that are available for web apps:
- Firebase Authentication andFirebase UI to easily allow your users to sign in to your app.
- Cloud Firestore to save structured data on the cloud and get instant notification when data changes.
- Firebase Security Rules to secure your database.
Some of these products need special configuration or need to be enabled using the Firebase console.
Enable email sign-in for Firebase Authentication
To allow users to sign in to the web app, you'll use theEmail/Password sign-in method for this codelab:
- In the left-side panel of the Firebase console, clickBuild >Authentication. Then clickGet Started. You're now in the Authentication dashboard, where you can see signed-up users, configure sign-in providers, and manage settings.

- Select theSign-in method tab (orclick here to go directly to the tab).

- ClickEmail/Password from the provider options, toggle the switch toEnable, and then clickSave.

Set up Cloud Firestore
The web app usesCloud Firestore to save chat messages and receive new chat messages.
Here's how to set up Cloud Firestore in your Firebase project:
- In the left-panel of the Firebase console, expandBuild and then selectFirestore database.
- ClickCreate database.
- Leave theDatabase ID set to
(default). - Select a location for your database, then clickNext.
For a real app, you want to choose a location that's close to your users. - ClickStart in test mode. Read the disclaimer about the security rules.
Later in this codelab, you'll add Security Rules to secure your data.Donot distribute or expose an app publicly without adding Security Rules for your database. - ClickCreate.
5. Add and configure Firebase
Now that you have your Firebase project created and some services enabled, you need to tell the code that you want to use Firebase, as well as which Firebase project to use.
Add the Firebase libraries
For your app to use Firebase, you need to add the Firebase libraries to the app. There are multiple ways to do this, asdescribed in the Firebase documentation. For example, you can add the libraries from Google's CDN, or you can install them locally using npm and then package them in your app if you're using Browserify.
StackBlitz provides automatic bundling, so you can add the Firebase libraries using import statements. You will be using the modular (v9) versions of the libraries, which help reduce the overall size of the webpage though a process called "tree shaking". You can learn more about the modular SDKsin the docs.
To build this app, you use the Firebase Authentication, FirebaseUI, and Cloud Firestore libraries. For this codelab, the following import statements are already included at the top of theindex.js file, and we'll be importing more methods from each Firebase library as we go:
//Importstylesheetsimport'./style.css';//FirebaseApp(thecoreFirebaseSDK)isalwaysrequiredimport{initializeApp}from'firebase/app';//AddtheFirebaseproductsandmethodsthatyouwanttouseimport{}from'firebase/auth';import{}from'firebase/firestore';import*asfirebaseuifrom'firebaseui';Add a Firebase web app to your Firebase project
- Back in the Firebase console, navigate to your project's overview page by clickingProject Overview in the top left.
- In the center of your project's overview page, click the web icon
to create a new Firebase web app.
- Register the app with the nicknameWeb App.
- For this codelab, do NOT check the box next toAlso set up Firebase Hosting for this app. You'll use StackBlitz's preview pane for now.
- ClickRegister app.
Stackblitz manages your dependencies for you, so you can skip the
npm install firebasestep that's displayed in the console.
- Copy theFirebase configuration object to your clipboard.

- ClickContinue to console.Add the Firebase configuration object to your app:
- Back in StackBlitz, go to the
index.jsfile. - Locate the
Add Firebase project configuration object herecomment line, then paste your configuration snippet just below the comment. - Add the
initializeAppfunction call to set up Firebase using your unique Firebase project configuration.//...//AddFirebaseprojectconfigurationobjecthereconstfirebaseConfig={apiKey:"random-unique-string",authDomain:"your-projectId.firebaseapp.com",databaseURL:"https://your-projectId.firebaseio.com",projectId:"your-projectId",storageBucket:"your-projectId.firebasestorage.app",messagingSenderId:"random-unique-string",appId:"random-unique-string",};//InitializeFirebaseinitializeApp(firebaseConfig);
If you missed thefirebaseConfigsnippet (or need it at a checkpoint)...
You can get your Firebase project configuration object from the Firebase console.
- In the Firebase console, click the settings icon in the top-left corner, then selectProject settings.
- In theGeneral tab, scroll down to theYour apps card.
- Click on your web app, then select theConfig option for the Firebase SDK snippet.
- Copy the entire configuration snippet to your clipboard.

6. Add user sign-in (RSVP)
Now that you've added Firebase to the app, you can set up an RSVP button that registers people usingFirebase Authentication.
Authenticate your users with Email Sign-In and FirebaseUI
You'll need an RSVP button that prompts the user to sign in with their email address. You can do this by hooking upFirebaseUI to an RSVP button.FirebaseUI is a library which gives you a pre-built UI on top of Firebase Auth.
FirebaseUI requires a configuration (see the options in thedocumentation) that does two things:
- Tells FirebaseUI that you want to use theEmail/Password sign-in method.
- Handles the callback for a successful sign-in and returns false to avoid a redirect. You don't want the page to refresh because you're building a single-page web app.
Add the code to initialize FirebaseUI Auth
- In StackBlitz, go to the
index.jsfile. - At the top, locate the
firebase/authimport statement, then addgetAuthandEmailAuthProvider, like so://...//AddtheFirebaseproductsandmethodsthatyouwanttouseimport{getAuth,EmailAuthProvider}from'firebase/auth';import{}from'firebase/firestore'; - Save a reference to the auth object right after
initializeApp, like so:initializeApp(firebaseConfig);auth = getAuth(); - Notice that the FirebaseUI configuration is already provided in the starting code. It's already setup to use the email auth provider.
- At the bottom of the
main()function inindex.js, add the FirebaseUI initialization statement, like so:asyncfunctionmain(){//...//InitializetheFirebaseUIwidgetusingFirebaseconstui=newfirebaseui.auth.AuthUI(auth);}main();
Add an RSVP button to the HTML
- In StackBlitz, go to the
index.htmlfile. - Add the HTML for an RSVP button inside the
event-details-containeras shown in the example below.
Be careful to use the sameidvalues as shown below because, for this codelab, there are already hooks for these specific IDs in theindex.jsfile.
Note that in theindex.htmlfile, there's a container with the IDfirebaseui-auth-container. This is the ID that you'll pass to FirebaseUI to hold your login. App preview<!-- ... --><section> <!-- ... --> <!-- ADD THE RSVP BUTTON HERE --> <button>RSVP</button></section><hr><section></section><!-- ... -->
- Set up a listener on the RSVP button and call the FirebaseUI start function. This tells FirebaseUI that you want to see the sign-in window.
Add the following code to the bottom of themain()function inindex.js:async function main() { // ... // Listen to RSVP button clicks startRsvpButton.addEventListener("click", () => { ui.start("#firebaseui-auth-container", uiConfig); });}main();
Test signing in to the app
- In StackBlitz's preview window, click the RSVP button to sign in to the app.
- For this codelab, you can use any email address, even a fake email address, since you're not setting up an email verification step for this codelab.
- If you see an error message stating
auth/operation-not-allowedorThe given sign-in provider is disabled for this Firebase project, check to make sure that you enabledEmail/Password as a sign-in provider in the Firebase console.

- Go to theAuthentication dashboard in the Firebase console. In theUsers tab, you should see the account information that you entered to sign in to the app.

Tip: Check out theFirebase documentation to learn how to use FirebaseUI and Firebase Authentication to add social sign-in providers (such as GitHub, Google, and Facebook) to your app.
Add authentication state to the UI
Next, make sure that the UI reflects the fact that you're signed in.
You'll use the Firebase Authentication state listener callback, which gets notified whenever the user's sign-in status changes. If there's currently a signed-in user, your app will switch the "RSVP" button to a "logout" button.
- In StackBlitz, go to the
index.jsfile. - At the top, locate the
firebase/authimport statement, then addsignOutandonAuthStateChanged, like so://...//AddtheFirebaseproductsandmethodsthatyouwanttouseimport{getAuth,EmailAuthProvider,signOut,onAuthStateChanged}from'firebase/auth';import{}from'firebase/firestore'; - Add the following code at the bottom of the
main()function:async function main() { // ... // Listen to the current Auth state onAuthStateChanged(auth, user => { if (user) { startRsvpButton.textContent = 'LOGOUT'; } else { startRsvpButton.textContent = 'RSVP'; } });}main(); - In the button listener, check whether there is a current user and log them out. To do this,replace the current
startRsvpButton.addEventListenerwith the following:// ...// Called when the user clicks the RSVP buttonstartRsvpButton.addEventListener('click',()=>{if(auth.currentUser){// User is signed in; allows user to sign outsignOut(auth);}else{// No user is signed in; allows user to sign inui.start('#firebaseui-auth-container',uiConfig);}});
Now, the button in your app should showLOGOUT, and it should switch back toRSVP when it's clicked.
App preview

Are you stuck or think that you might be off track? Here's a StackBlitz link that's updated with all of the code added up to this point of the codelab:https://stackblitz.com/edit/firebase-gtk-web-checkpoint1
Make sure that you do two things at this checkpoint:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console.
7. Write messages to Cloud Firestore
Knowing that users are coming is great, but let's give the guests something else to do in the app. What if they could leave messages in a guestbook? They can share why they're excited to come or who they hope to meet.
To store the chat messages that users write in the app, you'll useCloud Firestore.
Data model
Cloud Firestore is a NoSQL database, and data stored in the database is split into collections, documents, fields, and subcollections. You will store each message of the chat as a document in a top-level collection calledguestbook.

Tip: To learn more about the Cloud Firestore data model, read about documents and collections inthe Cloud Firestore documentation. You can also watch agreat series of videos that describe the Cloud Firestore NoSQL data model, queries, and other cool things that you can do with Cloud Firestore.
Add messages to Firestore
In this section, you'll add the functionality for users to write new messages to the database. First, you add the HTML for the UI elements (message field and send button). Then, you add the code that hooks these elements up to the database.
To add the UI elements of a message field and a send button:
- In StackBlitz, go to the
index.htmlfile. - Locate the
guestbook-container, then add the following HTML to create a form with the message input field and the send button.<!--...--><sectionid="guestbook-container"><h2>Discussion</h2><formid="leave-message"><label>Leaveamessage:</label><inputtype="text"id="message"><buttontype="submit"><iclass="material-icons">send</i><span>SEND</span></button></form></section><!--...-->
App preview

A user clicking theSEND button will trigger the code snippet below. It adds the contents of the message input field to theguestbook collection of the database. Specifically, theaddDoc method adds the message content to a new document (with an automatically generated ID) to theguestbook collection.
- In StackBlitz, go to the
index.jsfile. - At the top, locate the
firebase/firestoreimport statement, then addgetFirestore,addDoc, andcollection, like so://...//AddtheFirebaseproductsandmethodsthatyouwanttouseimport{getAuth,EmailAuthProvider,signOut,onAuthStateChanged}from'firebase/auth';import{getFirestore,addDoc,collection}from'firebase/firestore'; - Now we'll save a reference to the Firestore
dbobject right afterinitializeApp:initializeApp(firebaseConfig);auth = getAuth();db = getFirestore(); - At the bottom of the
main()function, add the following code.
Note thatauth.currentUser.uidis a reference to the auto-generated unique ID that Firebase Authentication gives for all logged-in users.asyncfunctionmain(){//...//Listentotheformsubmissionform.addEventListener('submit',asynce=>{//Preventthedefaultformredirecte.preventDefault();//Writeanewmessagetothedatabasecollection"guestbook"addDoc(collection(db,'guestbook'),{text:input.value,timestamp:Date.now(),name:auth.currentUser.displayName,userId:auth.currentUser.uid});//clearmessageinputfieldinput.value='';//Returnfalsetoavoidredirectreturnfalse;});}main();
Show the guestbook only to signed-in users
You don't want justanybody to see the guests' chat. One thing that you can do to secure the chat is to allow only signed-in users to view the guestbook. That said, for your own apps, you'll want to also secure your database withFirebase Security Rules. (There's more information on security rules later in the codelab.)
- In StackBlitz, go to the
index.jsfile. - Edit the
onAuthStateChangedlistener to hide and show the guestbook.// ...// Listen to the current Auth stateonAuthStateChanged(auth,user=>{if(user){startRsvpButton.textContent='LOGOUT';// Show guestbook to logged-in usersguestbookContainer.style.display='block';}else{startRsvpButton.textContent='RSVP';// Hide guestbook for non-logged-in usersguestbookContainer.style.display='none';}});
Test sending messages
- Make sure that you're signed in to the app.
- Enter a message such as "Hey there!", then clickSEND.
This action writes the message to your Cloud Firestore database. However, you won't yet see the message in your actual web app because you still need to implement retrieving the data. You'll do that next.
But you can see the newly added message in the Firebase console.
In the Firebase console, in theFirestore Database dashboard, you should see theguestbook collection with your newly added message. If you keep sending messages, your guestbook collection will contain many documents, like this:
Firebase console

Are you stuck or think that you might be off track? Here's a StackBlitz link that's updated with all of the code added up to this point of the codelab:https://stackblitz.com/edit/firebase-gtk-web-checkpoint2
Make sure that you do two things at this checkpoint:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console.
8. Read messages
Synchronize messages
It's lovely that guests can write messages to the database, but they can't see them in the app yet.
To display messages, you'll need to add listeners that trigger when data changes, then create a UI element that shows new messages.
You'll add code that listens for newly added messages from the app. First, add a section in the HTML to show messages:
- In StackBlitz, go to the
index.htmlfile. - In
guestbook-container, add a new section with the ID ofguestbook.<!-- ... --> <section> <h2>Discussion</h2> <form><!-- ... --></form> <section></section> </section><!-- ... -->
Next, register the listener that listens for changes made to the data:
- In StackBlitz, go to the
index.jsfile. - At the top, locate the
firebase/firestoreimport statement, then addquery,orderBy, andonSnapshot, like so://...import{getFirestore,addDoc,collection,query,orderBy,onSnapshot}from'firebase/firestore'; - At the bottom of the
main()function, add the following code to loop through all the documents (guestbook messages) in the database. To learn more about what's happening in this code, read the information below the snippet.asyncfunctionmain(){//...//Createqueryformessagesconstq=query(collection(db,'guestbook'),orderBy('timestamp','desc'));onSnapshot(q,snaps=>{//Resetpageguestbook.innerHTML='';//Loopthroughdocumentsindatabasesnaps.forEach(doc=>{//CreateanHTMLentryforeachdocumentandaddittothechatconstentry=document.createElement('p');entry.textContent=doc.data().name+': '+doc.data().text;guestbook.appendChild(entry);});});}main();
To listen to messages in the database, you've created a query on a specific collection by using thecollection function. The code above listens to the changes in theguestbook collection, which is where the chat messages are stored. The messages are also ordered by date, usingorderBy('timestamp', 'desc') to display the newest messages at the top.
TheonSnapshot function takes two parameters: the query to use and a callback function. The callback function is triggered when there are any changes to documents that match the query. This could be if a message gets deleted, modified, or added. For more information, see theCloud Firestore documentation.
Tip: For a faster refresh, you can update only the changed documents, instead of the whole list. Learn more in theCloud Firestore documentation.
Test synchronizing messages
Cloud Firestore automatically and instantly synchronizes data with clients subscribed to the database.
- The messages that you created earlier in the database should be displayed in the app. Feel free to write new messages; they should appear instantly.
- If you open your workspace in multiple windows or tabs, messages will sync in real time across tabs.
- (Optional) You can try manually deleting, modifying, or adding new messages directly in theDatabase section of the Firebase console; any changes should appear in the UI.
Congratulations! You're reading Cloud Firestore documents in your app!
App preview

Are you stuck or think that you might be off track? Here's a StackBlitz link that's updated with all of the code added up to this point of the codelab:https://stackblitz.com/edit/firebase-gtk-web-checkpoint3
Make sure that you do two things at this checkpoint:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console.
9. Set up basic security rules
You initially set up Cloud Firestore to use test mode, meaning that your database is open for reads and writes. However, you should only use test mode during very early stages of development. As a best practice, you should set up security rules for your database as you develop your app. Security should be integral to your app's structure and behavior.
Security Rules allow you to control access to documents and collections in your database. The flexible rules syntax allows you to create rules that match anything from all writes to the entire database to operations on a specific document.
You can write security rules for Cloud Firestore in the Firebase console:
- In the Firebase console'sBuild section, clickFirestore Database, then select theRules tab (orclick here to go directly to theRules tab).
- You should see the following default security rules, with a public-access time limit a couple of weeks from today.

Check out theFirebase Security Rules documentation or thisYouTube playlist to learn more about security rules.
Identify collections
First, identify the collections to which the app writes data.
- Delete the existing
match /{document=**}clause, so your rules look like this:rules_version = '2';service cloud.firestore { match /databases/{database}/documents { }} - In
match /databases/{database}/documents, identify the collection that you want to secure:rules_version = '2';service cloud.firestore { match /databases/{database}/documents { match /guestbook/{entry} { // You'll add rules here in the next step. }}
Add security rules
Because you used the Authentication UID as a field in each guestbook document, you can get the Authentication UID and verify that anyone attempting to write to the document has a matching Authentication UID.
- Add the read and write rules to your rule set as shown below:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{match/guestbook/{entry}{allowread:ifrequest.auth.uid!=null;allowcreate:ifrequest.auth.uid==request.resource.data.userId;}}} - ClickPublish to deploy your new rules.Now, for the guestbook, only signed-in users can read messages (any message!), but you can only create a message using your user ID. We also don't allow messages to be edited or deleted.
Add validation rules
- Add data validation to make sure that all of the expected fields are present in the document:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{match/guestbook/{entry}{allowread:ifrequest.auth.uid!=null;allowcreate:ifrequest.auth.uid==request.resource.data.userId &&"name"inrequest.resource.data &&"text"inrequest.resource.data &&"timestamp"inrequest.resource.data;}}} - ClickPublish to deploy your new rules.
Reset listeners
Because your app now only allows authenticated users to log in, you should move the guestbookfirestore query inside the Authentication listener. Otherwise, permission errors will occur and the app will be disconnected when the user logs out.
- In StackBlitz, go to the
index.jsfile. - Pull the guestbook collection
onSnapshotlistener into a new function calledsubscribeGuestbook. Also, assign the results of theonSnapshotfunction to theguestbookListenervariable.
The FirestoreonSnapshotlistenerreturns an unsubscribe function that you'll be able to use to cancel the snapshot listener later.//...//ListentoguestbookupdatesfunctionsubscribeGuestbook(){constq=query(collection(db,'guestbook'),orderBy('timestamp','desc'));guestbookListener=onSnapshot(q,snaps=>{//Resetpageguestbook.innerHTML='';//Loopthroughdocumentsindatabasesnaps.forEach(doc=>{//CreateanHTMLentryforeachdocumentandaddittothechatconstentry=document.createElement('p');entry.textContent=doc.data().name+': '+doc.data().text;guestbook.appendChild(entry);});});} - Add a new function underneath called
unsubscribeGuestbook. Check whether theguestbookListenervariable is not null, then call the function to cancel the listener.// ...// Unsubscribe from guestbook updatesfunctionunsubscribeGuestbook(){if(guestbookListener!=null){guestbookListener();guestbookListener=null;}}
Finally, add the new functions to theonAuthStateChanged callback.
- Add
subscribeGuestbook()at the bottom ofif (user). - Add
unsubscribeGuestbook()at the bottom of theelsestatement.// ...// Listen to the current Auth stateonAuthStateChanged(auth,user=>{if(user){startRsvpButton.textContent='LOGOUT';// Show guestbook to logged-in usersguestbookContainer.style.display='block';// Subscribe to the guestbook collectionsubscribeGuestbook();}else{startRsvpButton.textContent='RSVP';// Hide guestbook for non-logged-in usersguestbookContainer.style.display='none';// Unsubscribe from the guestbook collectionunsubscribeGuestbook();}});
Are you stuck or think that you might be off track? Here's a StackBlitz link that's updated with all of the code added up to this point of the codelab:https://stackblitz.com/edit/firebase-gtk-web-checkpoint4
Make sure that you do two things at this checkpoint:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console.
10. Bonus step: Practice what you've learned
Record an attendee's RSVP status
Right now, your app just allows people to start chatting if they're interested in the event. Also, the only way you know if someone's coming is if they post it in the chat. Let's get organized and let people know how many people are coming.
You'll add a toggle to register people who want to attend the event, then collect a count of how many people are coming.
- In StackBlitz, go to the
index.htmlfile. - In
guestbook-container, add a set ofYES andNO buttons, like so:<!-- ... --> <section> <h2>Are you attending?</h2> <button>YES</button> <button>NO</button> <h2>Discussion</h2> <!-- ... --> </section><!-- ... -->
App preview

Next, register the listener for button clicks. If the user clicksYES, then use their Authentication UID to save the response to the database.
- In StackBlitz, go to the
index.jsfile. - At the top, locate the
firebase/firestoreimport statement, then adddoc,setDoc, andwhere, like so://...//AddtheFirebaseproductsandmethodsthatyouwanttouseimport{getFirestore,addDoc,collection,query,orderBy,onSnapshot,doc,setDoc,where}from'firebase/firestore'; - At the bottom of the
main()function, add the following code to listen to the RSVP status:async function main() { // ... // Listen to RSVP responses rsvpYes.onclick = async () => { }; rsvpNo.onclick = async () => { };}main(); - Next, create a new collection called
attendees, then register a document reference if either RSVP button is clicked. Set that reference totrueorfalsedepending on which button is clicked.
First, forrsvpYes: Then, the same for//...//ListentoRSVPresponsesrsvpYes.onclick=async()=>{//Getareferencetotheuser's document in the attendees collectionconstuserRef=doc(db,'attendees',auth.currentUser.uid);//IftheyRSVP'd yes, save a document with attendi()ng: truetry{awaitsetDoc(userRef,{attending:true});}catch(e){console.error(e);}};rsvpNo, but with the valuefalse:rsvpNo.onclick=async()=>{//Getareferencetotheuser's document in the attendees collectionconstuserRef=doc(db,'attendees',auth.currentUser.uid);//IftheyRSVP'd yes, save a document with attending: truetry{awaitsetDoc(userRef,{attending:false});}catch(e){console.error(e);}};
Update your Security Rules
Because you already have some rules set up, the new data that you're adding with the buttons is going to be rejected.
Allow additions to theattendees collection
You'll need to update the rules to allow adding to theattendees collection.
- For the
attendeescollection, since you used the Authentication UID as the document name, you can grab it and verify that the submitter'suidis the same as the document they are writing. You'll allow everyone to read the attendees list (since there is no private data there), but only the creator should be able to update it.rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//...//match/attendees/{userId}{allowread:iftrue;allowwrite:ifrequest.auth.uid==userId;}}} - ClickPublish to deploy your new rules.
Add validation rules
- Add some data validation rules to make sure that all of the expected fields are present in the document:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{//...//match/attendees/{userId}{allowread:iftrue;allowwrite:ifrequest.auth.uid==userId &&"attending"inrequest.resource.data;}}} - Don't forget to clickPublish to deploy your rules!
(Optional) You can now view the results of clicking the buttons. Go to your Cloud Firestore dashboard in the Firebase console.
Read RSVP status
Now that you've recorded the responses, let's see who's coming and reflect it in the UI.
- In StackBlitz, go to the
index.htmlfile. - In
description-container, add a new element with the ID ofnumber-attending.<!-- ... --> <section> <!-- ... --> <p></p> </section><!-- ... -->
Next, register the listener for theattendees collection and count the number ofYES responses:
- In StackBlitz, go to the
index.jsfile. - At the bottom of the
main()function, add the following code to listen to the RSVP status and countYES clicks.asyncfunctionmain(){//...//ListenforattendeelistconstattendingQuery=query(collection(db,'attendees'),where('attending','==',true));constunsubscribe=onSnapshot(attendingQuery,snap=>{constnewAttendeeCount=snap.docs.length;numberAttending.innerHTML=newAttendeeCount+' people going';});}main();
Finally, let's highlight the button corresponding to the current status.
- Create a function that checks whether the current Authentication UID has an entry in the
attendeescollection, then set the button class toclicked.//...//ListenforattendeelistfunctionsubscribeCurrentRSVP(user){constref=doc(db,'attendees',user.uid);rsvpListener=onSnapshot(ref,doc=>{if(doc &&doc.data()){constattendingResponse=doc.data().attending;//Updatecssclassesforbuttonsif(attendingResponse){rsvpYes.className='clicked';rsvpNo.className='';}else{rsvpYes.className='';rsvpNo.className='clicked';}}});} - Also, let's make a function to unsubscribe. This will be used when the user logs out.
// ...functionunsubscribeCurrentRSVP(){if(rsvpListener!=null){rsvpListener();rsvpListener=null;}rsvpYes.className='';rsvpNo.className='';} - Call the functions from the Authentication listener.
// ...// Listen to the current Auth state// Listen to the current Auth stateonAuthStateChanged(auth,user=>{if(user){startRsvpButton.textContent='LOGOUT';// Show guestbook to logged-in usersguestbookContainer.style.display='block';// Subscribe to the guestbook collectionsubscribeGuestbook();// Subscribe to the user's RSVPsubscribeCurrentRSVP(user);}else{startRsvpButton.textContent='RSVP';// Hide guestbook for non-logged-in usersguestbookContainer.style.display='none';// Unsubscribe from the guestbook collectionunsubscribeGuestbook();// Unsubscribe from the guestbook collectionunsubscribeCurrentRSVP();}}); - Try logging in as multiple users and see the count increase with each additionalYES button click.
App preview

Are you stuck or think that you might be off track? Here's a StackBlitz link that's updated with all of the code added up to this point of the codelab:https://stackblitz.com/edit/firebase-gtk-web-checkpoint5
Make sure that you do two things at this checkpoint:
- Fork the project so that it's your own.
- Add your Firebase project configuration object from the Firebase console.
11. Congratulations!
You've used Firebase to build an interactive, real-time web application!
What we've covered
- Firebase Authentication
- FirebaseUI
- Cloud Firestore
- Firebase Security Rules
Next steps
- Want to learn more the Firebase Developer Workflow? Check out theFirebase emulator codelab to learn about how to test and run your app completely locally.
- Want to learn more about other Firebase products? Maybe you want to store image files that users upload? Or send notifications to your users? Check out theFirebase web codelab for a codelab that goes into more depth on many more Firebase products for web.
- Want to learn more about Cloud Firestore? Maybe you want to learn about subcollections and transactions? Head over to theCloud Firestore web codelab for a codelab that goes into more depth on Cloud Firestore. Or check out thisYouTube series to get to know Cloud Firestore!
Learn more
- Firebase site:firebase.google.com
- Firebase YouTube channel
How did it go?
We would love your feedback! Please fill out a (very) short formhere.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.