20 April 2023
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.
Before we start building our chat application, we need to set up Firebase.
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.
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.
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
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.
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.
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.
Chat.svelte
.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.
Now that we have created the chat room, let's implement the functionality to send and receive messages in real-time.
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.
<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.
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} />
<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.
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.
In your Svelte project, create a new file called MessageList.svelte
.
In the MessageList.svelte
file, import the Message
component that we created earlier:
<script> import Message from './Message.svelte'; </script>
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>
The Message
component expects a message
prop that contains the message data. Pass the message
object to the Message
component using the {message}
syntax.
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>
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
CONTACT
+44 (0)20 8446 7555
Copyright © 2023 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