CUSTOMISED
Expert-led training for your team
Dismiss
Building Real-Time Web Apps with Svelte.js and Firebase

20 April 2023

Building Real-Time Web Apps with Svelte.js and Firebase

I. Introduction to Svelte.js and Firebase for Real-Time Web Apps

Real-time web apps are applications that provide instant feedback to users and update data in real-time without requiring a page refresh. Real-time web apps have become increasingly popular due to the need for real-time updates in areas such as social media, chat apps, and real-time gaming.

Svelte.js is a JavaScript framework that enables developers to build efficient and reactive web applications. Svelte.js provides a different approach to building web applications than other frameworks such as React and Vue.js. Svelte.js compiles code at build time, which results in faster load times and better performance.

Firebase is a backend platform that provides a variety of features for building real-time applications, such as authentication, cloud messaging, and real-time database. Firebase Realtime Database is a cloud-hosted NoSQL database that stores data in JSON format and provides real-time synchronization between clients.

Using Svelte.js and Firebase together can result in fast and efficient real-time web applications with minimal code. In this article, we'll explore how to build a simple chat application using Svelte.js and Firebase Realtime Database.

Stay tuned for the next section on setting up Firebase.

II. Setting Up Firebase

Before we start building our chat application, we need to set up Firebase.

  1. Sign up for Firebase: If you don't already have a Firebase account, go to firebase.google.com and sign up for a free account.

  2. Create a Firebase project: Once you have signed up, create a new Firebase project by clicking on the "Add Project" button on the Firebase console. Follow the prompts to create your project.

  3. Add Firebase to the Svelte.js app: In your Svelte.js app, install the Firebase JavaScript SDK using npm. Run the following command in your terminal:

npm install firebase

  1. Initialize Firebase: In your Svelte.js app, import the Firebase SDK and initialize Firebase with your Firebase project configuration. You can find your project configuration by going to your Firebase console and clicking on the "Project Settings" button. Copy and paste the configuration code into your Svelte.js app, like this:

import firebase from 'firebase/app'; import 'firebase/database'; const firebaseConfig = { apiKey: 'YOUR_API_KEY', authDomain: 'YOUR_AUTH_DOMAIN', databaseURL: 'YOUR_DATABASE_URL', projectId: 'YOUR_PROJECT_ID', storageBucket: 'YOUR_STORAGE_BUCKET', messagingSenderId: 'YOUR_MESSAGING_SENDER_ID', appId: 'YOUR_APP_ID', measurementId: 'YOUR_MEASUREMENT_ID', }; firebase.initializeApp(firebaseConfig); export const db = firebase.database();

This code initializes Firebase and exports the Firebase Realtime Database instance as a db variable, which we will use to read and write data to the database.

Congratulations! You have now set up Firebase for your Svelte.js app. In the next section, we will start building our chat application.

III. Building the Chat Application with Svelte.js and Firebase

In this section, we will start building our real-time chat application using Svelte.js and Firebase Realtime Database. We will build a simple chat application that allows users to send and receive messages in real-time.

A. Creating the Chat Room

The first step in building our chat application is creating the chat room. The chat room is where all the messages will be displayed and where users can enter their messages.

  1. In your Svelte.js app, create a new file called Chat.svelte.
  2. In the Chat.svelte file, add the following code:

<script> import { onMount } from 'svelte'; import { db } from './firebase'; let messages = []; onMount(() => { // Listen for changes to the "messages" node in Firebase Realtime Database db.ref('messages').on('value', (snapshot) => { // Update the messages array with the latest messages messages = Object.values(snapshot.val()); }); }); </script> <style> /* Chat room styles */ </style> <div class="chat-room"> <!-- Display the messages here --> </div> <!-- Input field for sending messages --> <input type="text" placeholder="Type your message..." />

In this code, we use the onMount function from Svelte.js to listen for changes to the "messages" node in Firebase Realtime Database. When there is a change, we update the messages array with the latest messages.

We also added an input field where users can enter their messages. We will implement the functionality to send messages in the next step.

B. Sending and Receiving Messages

Now that we have created the chat room, let's implement the functionality to send and receive messages in real-time.

  1. In the Chat.svelte file, add the following code to the <script> section:

import { onMount } from 'svelte'; import { db } from './firebase'; let messages = []; let newMessage = ''; onMount(() => { // Listen for changes to the "messages" node in Firebase Realtime Database db.ref('messages').on('value', (snapshot) => { // Update the messages array with the latest messages messages = Object.values(snapshot.val()); }); }); function sendMessage() { // Add the new message to the Firebase Realtime Database db.ref('messages').push({ message: newMessage, timestamp: Date.now(), }); // Clear the input field newMessage = ''; }

In this code, we added a newMessage variable to store the new message entered by the user. We also created a sendMessage function that adds the new message to the Firebase Realtime Database and clears the input field.

  1. Update the <div> tag in the Chat.svelte file to display the messages array:

<div class="chat-room"> {#each messages as message} <p>{message.message}</p> {/each} </div>

Now, when a new message is added to the Firebase Realtime Database, the messages array is updated with the latest messages, and the messages are displayed in the chat room.

  1. Add an on:input event to the input field to update the newMessage variable:

<input type="text" placeholder="Type your message..." on:input={(event) => newMessage = event.target.value} />

  1. Add an `on ChatRoom.svelte file, we will create the basic layout for our chat room component. Here's the code:

<script> import { onMount } from 'svelte'; import { collection, addDoc, query, orderBy, limit, onSnapshot } from 'firebase/firestore'; import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; // Firebase configuration object const firebaseConfig = { // Your Firebase project configuration }; // Initialize Firebase firebase.initializeApp(firebaseConfig); // Firestore database reference const db = firebase.firestore(); // Authentication reference const auth = firebase.auth(); // Google authentication provider const provider = new GoogleAuthProvider(); let messages = []; onMount(() => { const q = query(collection(db, 'messages'), orderBy('timestamp', 'desc'), limit(50)); const unsubscribe = onSnapshot(q, (querySnapshot) => { messages = []; querySnapshot.forEach((doc) => { messages.unshift(doc.data()); }); }); return unsubscribe; }); const login = async () => { try { await signInWithPopup(auth, provider); } catch (error) { console.log(error); } }; const sendMessage = async (event) => { event.preventDefault(); const messageInput = event.target.querySelector('input[name="message"]'); const message = messageInput.value.trim(); if (message === '') return; messageInput.value = ''; const { uid, displayName, photoURL } = auth.currentUser; await addDoc(collection(db, 'messages'), { uid, displayName, photoURL, message, timestamp: Date.now(), }); }; </script> <style> /* Add your own CSS here */ </style> <div class="chat-room"> <h1>Chat Room</h1> {#if !auth.currentUser} <button on:click={login}>Login with Google</button> {:else} <form on:submit={sendMessage}> <input type="text" name="message" placeholder="Type your message here..." /> <button type="submit">Send</button> </form> {#each messages as message} <div class="message"> <img src={message.photoURL} alt={message.displayName} /> <div> <h3>{message.displayName}</h3> <p>{message.message}</p> </div> </div> {/each} {/if} </div>

Let's go through this code step by step.

First, we import the necessary Firebase libraries and initialize the Firebase app with our configuration object. We also create a reference to the Firestore database and the Firebase authentication service.

import { onMount } from 'svelte'; import { collection, addDoc, query, orderBy, limit, onSnapshot } from 'firebase/firestore'; import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'; // Firebase configuration object const firebaseConfig = { // Your Firebase project configuration }; // Initialize Firebase firebase.initializeApp(firebaseConfig); // Firestore database reference const db = firebase.firestore(); // Authentication reference const auth = firebase.auth(); // Google authentication provider const provider = new GoogleAuthProvider(); let messages = []; // Listen for new messages onMount(() => { const q = query(collection(db, 'messages'), orderBy('timestamp', 'desc'), limit(50)); const unsubscribe = onSnapshot(q, (querySnapshot) => { messages = []; querySnapshot.forEach((doc) => { messages

To summarize what we've covered in this section: we've added a listener to the Firebase Firestore collection to get real-time updates whenever a new message is added or an existing message is updated. We also added a let variable to hold an array of messages that will be used to display messages in the UI.

In the next section, we'll create a Svelte component to display the list of messages in the UI.

Creating a Svelte Component to Display Messages

Now that we have set up the Firebase listener to get real-time updates, let's create a Svelte component to display the messages in the UI.

  1. In your Svelte project, create a new file called MessageList.svelte.

  2. In the MessageList.svelte file, import the Message component that we created earlier:

 

<script> import Message from './Message.svelte'; </script>

  1. Next, create a ul element to display the list of messages. Inside the ul element, use the each block to loop through the messages array that we created earlier and render each Message component:

<ul> {#each messages as message} <Message {message} /> {/each} </ul>

  1. The Message component expects a message prop that contains the message data. Pass the message object to the Message component using the {message} syntax.

  2. Save the MessageList.svelte file and open the App.svelte file. Import the MessageList component and add it to the template:

 

<script> import MessageList from './MessageList.svelte'; </script> <main> <h1>Real-Time Chat App</h1> <form on:submit|preventDefault={sendMessage}> <input type="text" bind:value={message} /> <button type="submit">Send</button> </form> <MessageList /> </main>

  1. Save the App.svelte file and run your application. You should now see a list of messages in the UI, and new messages should be added to the list in real-time as they are added to the Firebase Firestore collection.

That's it! We've created a Svelte component to display the list of messages in the UI, and our real-time chat app is now complete. In the next section, we'll cover some advanced features that you can add to your app, such as user authentication and message filtering.

Section 4: Real-Time Database Updates with Firebase

Now that we have the ability to create and delete notes in real-time, let's explore how to use Firebase to store the notes and synchronize the data across all connected clients.

Setting Up Firebase

To use Firebase, we need to create a Firebase project and configure it with our Svelte.js application. Follow the instructions on the Firebase Console to create a new project.

Once you have created a new project, navigate to the "Project settings" and click on the "Web" tab. Create a new web app and take note of the Firebase configuration object that is generated.

Next, create a new file called firebaseConfig.js in the root of your Svelte.js project and paste the configuration object into it:

// firebaseConfig.js const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_AUTH_DOMAIN", databaseURL: "YOUR_DATABASE_URL", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_STORAGE_BUCKET", messagingSenderId: "YOUR_MESSAGING_SENDER_ID", appId: "YOUR_APP_ID", measurementId: "YOUR_MEASUREMENT_ID" }; export default firebaseConfig;

Make sure to replace the placeholders with the actual values from your Firebase configuration object.

Integrating Firebase Realtime Database

To use Firebase Realtime Database, we need to install the firebase package and import it into our Svelte.js application.

npm install firebase

Next, create a new file called firebase.js in the root of your Svelte.js project and add the following code:

// firebase.js import firebase from 'firebase/app'; import 'firebase/database'; import firebaseConfig from './firebaseConfig'; firebase.initializeApp(firebaseConfig); const database = firebase.database(); export default database;

This code initializes the Firebase app with our configuration object and exports the Firebase Realtime Database instance.

Storing Notes in Firebase

Now that we have integrated Firebase, let's update our Notes component to store notes in the Firebase Realtime Database. In the Notes component, we will use the onMount lifecycle function to listen for changes to the database and update the notes array accordingly:

// Notes.svelte <script> import { onMount } from 'svelte'; import database from '../firebase'; let notes = []; onMount(() => { database.ref('notes').on('value', snapshot => { notes = []; snapshot.forEach(noteSnapshot => { const note = noteSnapshot.val(); note.id = noteSnapshot.key; notes.push(note); }); }); }); function addNote() { const note = { title: 'New Note', body: '' }; database.ref('notes').push(note); } function deleteNote(id) { database.ref(`notes/${id}`).remove(); } </script> <h1>Notes</h1> <button on:click={addNote}>Add Note</button> <ul> {#each notes as note} <li key={note.id}> <button on:click={() => deleteNote(note.id)}>X</button> <h2>{note.title}</h2> <p>{note.body}</p> </li> {:else} <p>No notes found</p> {/each} </ul>

In the onMount function, we listen for changes to the notes reference in the database and update the notes array with the

We will also need to create a createNote function and a deleteNote function that interact with Firebase to create and delete notes, respectively, and update the notes array with the updated list of notes.

export async function createNote(title, content) { const noteRef = doc(db, 'notes', title); await setDoc(noteRef, { content }); return getNotes(); } export async function deleteNote(title) { const noteRef = doc(db, 'notes', title); await deleteDoc(noteRef); return getNotes(); }

With these functions, we can now create and delete notes by interacting with Firebase. The createNote function takes a title and content parameter, creates a new document in the notes collection with the title as its ID, and sets the content of the document to the content parameter. It then calls the getNotes function to retrieve the updated notes list and return it.

The deleteNote function takes a title parameter, finds the document in the notes collection with the matching title ID, and deletes it. Like createNote, it also calls getNotes to retrieve the updated notes list and return it.

Now that we have the ability to create and delete notes, we can integrate these functions into our Svelte app to allow users to interact with the notes in real-time. Let's do that in the next section.

Integrating Firebase with Svelte

Now that we have our Firebase app set up and our functions to create and delete notes, let's integrate Firebase with our Svelte app to allow for real-time updates.

First, we need to install the firebase and sveltefire packages. The firebase package provides the Firebase SDK, while sveltefire provides an easy way to use Firebase with Svelte.

npm install firebase sveltefire

Next, let's import the Firebase SDK and initialize it with our app's configuration. We'll do this in a new firebase.js file that we'll create in the src directory.

import { initializeApp } from 'firebase/app'; import { getFirestore } from 'firebase/firestore'; const firebaseConfig = { // replace with your app's configuration }; const app = initializeApp(firebaseConfig); const db = getFirestore(app); export { db };

This code imports the initializeApp function from the Firebase app module, which initializes the Firebase SDK with our app's configuration. It also imports the getFirestore function from the Firebase firestore module, which provides access to the Firestore database.

We then create a firebaseConfig object with our app's configuration, which we'll replace with our own app's configuration later. We initialize the Firebase SDK with this configuration using the initializeApp function, and get a reference to the Firestore database using the getFirestore function.

Finally, we export the db reference so that we can use it in our Svelte app.

Now that we have our Firebase app set up, let's integrate it with our Svelte app. We'll start by creating a new Notes component that will display the list of notes and allow users to create and delete notes.

Create a new file called Notes.svelte in the src directory with the following code:

<script> import { onMount } from 'svelte'; import { db } from './firebase.js'; import { createNote, deleteNote } from './firebaseUtils.js'; let notes = []; async function getNotes() { const notesCollection = collection(db, 'notes'); const querySnapshot = await getDocs(notesCollection); notes = querySnapshot.docs.map((doc) => doc.id); } async function addNote() { const title = prompt('Enter note title'); const content = prompt('Enter note content'); await createNote(title, content); } async function removeNote(title) { if (confirm(`Are you sure you want to delete "${title}"?`)) { await deleteNote(title); } } onMount(async () => { await getNotes(); }); </script> <h1>Notes</h1> <ul> {#each notes as note} <li> <button on:click={() => removeNote(note)}>-</button> {note} </li> {/each} </ul> <button on:click={addNote}>Add Note</button>

In this code, we import the onMount function from Svelte to listen for changes to the component's state. We also import the db reference from the firebase.js file we created earlier, as well as the createNote and deleteNote functions from the firebaseUtils.js file we created earlier.

We initialize the notes array to an empty array, and define an async function called getNotes that retrieves the list of notes from Firebase using the ` 

We initialize the notes array to an empty array, and define an async function called getNotes that retrieves the list of notes from Firebase using the collection method. We then add a snapshot listener to the collection, which updates the notes array whenever there are changes to the data in the Firebase database.

import { writable } from 'svelte/store'; import { db } from './firebase'; export const notes = writable([]); const getNotes = async () => { const snapshot = await db.collection('notes').get(); notes.set(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))); }; getNotes(); db.collection('notes').onSnapshot(snapshot => { notes.set(snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }))); });

In the above code, we first import the writable store from Svelte and the db instance from our firebase.js file. We then define a writable store called notes and initialize it to an empty array.

Next, we define the getNotes function, which uses the collection method from the db instance to retrieve all documents from the notes collection in our Firebase database. We then use the map method to convert each document into an object with an id property and all the remaining properties from the document's data.

Finally, we call the getNotes function to retrieve the initial list of notes, and add a snapshot listener to the notes collection, which updates the notes store with the new data whenever there are changes to the Firebase database.

This way, our Svelte app will always have the latest version of the notes data from Firebase, and any changes made by other users or devices will be immediately reflected in the UI.

In the next section, we'll look at how to create a form for adding new notes to our Firebase database.

Section 5: Real-Time Updates with Firebase

Firebase provides a real-time database that allows developers to build real-time applications with ease. In this section, we will leverage the Firebase real-time database to build real-time updates for our note-taking app.

Setting up Firebase Real-Time Database

To get started, we need to set up a Firebase project and enable the Firebase real-time database. If you already have a Firebase project set up, skip to the next step.

  1. Go to the Firebase Console and click on "Add project."
  2. Enter a name for your project and click "Continue."
  3. Choose your billing plan and click "Create Project."
  4. Once your project is created, click "Continue" to go to the project dashboard.
  5. Click on "Realtime Database" from the left menu and click on "Create Database."
  6. Choose "Start in test mode" and click "Next."
  7. Choose a location for your database and click "Done."

Now that we have set up our Firebase project and enabled the real-time database, we can start building real-time updates for our note-taking app.

Listening for Real-Time Updates

To listen for real-time updates in our app, we will use the on function from Firebase to listen for changes to the notes collection in the database.

// src/App.svelte import { onMount } from 'svelte'; import { db } from './firebase'; let notes = []; async function getNotes() { const querySnapshot = await db.collection('notes').get(); notes = querySnapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); } onMount(async () => { await getNotes(); db.collection('notes').onSnapshot(snapshot => { snapshot.docChanges().forEach(change => { const note = { id: change.doc.id, ...change.doc.data() }; switch (change.type) { case 'added': notes.push(note); break; case 'modified': const index = notes.findIndex(n => n.id === note.id); notes[index] = note; break; case 'removed': notes = notes.filter(n => n.id !== note.id); break; } }); }); });

In this code, we use the onMount function from Svelte.js to listen for changes to the component's state. When the component mounts, we call the getNotes function to retrieve the initial list of notes from Firebase.

We then use the onSnapshot function from Firebase to listen for changes to the notes collection in real-time. When a change is detected, the docChanges function returns an array of changes, which we loop over and handle accordingly. If a note is added, we add it to the notes array. If a note is modified, we update the corresponding note in the notes array. If a note is deleted, we remove it from the notes array.

With this code in place, our app now supports real-time updates. If multiple users are using the app at the same time, any changes made to the notes collection will be immediately reflected in all clients.

Conclusion

In this tutorial, we have built a note-taking app with Svelte.js and Firebase. We started by setting up a new Svelte.js project and creating a basic UI for our app. We then integrated Firebase into our app and used the Firebase Authentication API to add user authentication. Finally, we leveraged the Firebase real-time database to build real-time updates for our app.

With this app as a starting point, you can build a wide range of real-time web applications using Svelte.js and Firebase. Firebase Realtime Database is just one of the many Firebase services available that enable real-time functionality. You can also use Firebase Cloud Firestore or Firebase Cloud Messaging, depending on your specific use case.

In conclusion, Svelte.js is a powerful JavaScript framework for building real-time web applications. When combined with Firebase, you can build applications that update in real-time without the need for manual refreshes. By following the steps outlined in this article, you can build your own real-time web application with Svelte.js and Firebase.

here are some additional resources related to building real-time web apps with Svelte.js and Firebase:

I hope you find these resources helpful!

To train in Svelte.JS with JBI Training follow this link Svelte.js

About the author: Daniel West
Tech Blogger & Researcher for JBI Training

CONTACT
+44 (0)20 8446 7555

[email protected]

SHARE

 

Copyright © 2024 JBI Training. All Rights Reserved.
JB International Training Ltd  -  Company Registration Number: 08458005
Registered Address: Wohl Enterprise Hub, 2B Redbourne Avenue, London, N3 2BS

Modern Slavery Statement & Corporate Policies | Terms & Conditions | Contact Us

POPULAR

Rust training course                                                                          React training course

Threat modelling training course   Python for data analysts training course

Power BI training course                                   Machine Learning training course

Spring Boot Microservices training course              Terraform training course

Kubernetes training course                                                            C++ training course

Power Automate training course                               Clean Code training course