K O logo
Web Development

Project WebApp — Get firebase to sync your data

Author

Kalle

Date Published

 This AI-generated image presents a futuristic, high-tech workspace focused on web development, particularly using Firebase and React.js. The room is dominated by large, holographic displays on the walls, showcasing various data visualizations, code snippets, and icons related to Firebase services like Real-Time Database and Firestore. The central display features a glowing React logo hovering over an image of Earth, symbolizing global connectivity. Several workstations with multiple monitors are arranged around the room, each displaying lines of code. The workspace is bathed in warm, golden light, creating a sophisticated yet dynamic atmosphere. Additional details include a coffee mug with the React logo, a touch-sensitive table with holographic controls, and a few potted plants, adding a touch of greenery to the sleek, modern environment. The scene highlights the integration of cutting-edge technology and web development tools in a highly organized and visually immersive setting.

Till now the chat app is quite boring, because you can only talk to yourself. But for synchronization of the message history with other computers you need some external service to store the data and send notifications about changes. Firebase delivers an all-inclusive solution with a realtime database capable of syncing datasets to all connected clients.

The first step to get running is to create a new firebase app (or login with a google account). If you are logged in you should see something like this in the firebase console:

The image shows the Firebase console's welcome screen. It greets the user with "Welcome to Firebase!" and offers options to learn more, view documentation, or get support. Below, there are sections for recent projects, including an "Add project" button, a demo project, and other project cards.

The "Add project" button opens a wizard with some questions about your project, select what is fitting for you (region, data sharing with google...). After creating the app the only part missing is the database to enable data storage for your project click on "GET STARTED" on the Database tile and on the next screen select "Realtime Database". For the sake of simplicity select "start in test mode" but be aware to change the permissions as soon you go public with your app (rules documentation). Additionally, to the database the chat needs some kind of authentication to match messages to users. For the example anonymous authentication is enough to enable it select "Authentication" in the firebase app console. Under the "SIGN-IN METHOD" tab you can select the Anonymous provider and set it to "enabled".

That's it. Everything else is defined in the app code.

So next step is to install firebase:

npm install firebase

In the firebase console of your app you can get all config information when you click on "Add Firebase to your web app". To initialize the app import initializeApp from the package and call it with the copied config information:

1import { initializeApp } from "firebase";
2
3const config = {
4 apiKey: "YOUR_API_KEY_HERE",
5 authDomain: "AUTH_DOMAIN",
6 databaseURL: "DATABASE_URL",
7 projectId: "PROJECT_ID",
8 storageBucket: "STORAGE_BUCKET_URL",
9 messagingSenderId: "MESSAGING_SENDER_ID",
10};
11
12const app = initializeApp(config);

In the chat-app are two collections of data, users and messages. Each collection with its own rules how to write and read data.

All database requests begin with the same pattern, at first you need a reference of the data you want to work with.

1import { database } from "firebase";
2
3database(app).ref(`path/to/the/peace/of/data`);

The built up data-reference can get more specified with some query-functions like limitToLast(numberOfEntries) or orderByChild(childKey). When the query is fine you can use different functions to execute it, once(event_type) for is single time data-fetch, on(event_type, callback) for continuous updates, set(data) to update/create the data at the specified ref-address, push(data) to create a new entry in this collection.

The functions to read and write userData are then defined as this:

1const USERS_REF_NAME = "users";
2
3export async function getUser(userId) {
4 return (
5 await database(app).ref(`${USERS_REF_NAME}/${userId}`).once("value")
6 ).toJSON();
7}
8
9export async function writeUserData(userId, name, profilePic) {
10 await database(app).ref(`${USERS_REF_NAME}/${userId}`).set({
11 id: userId,
12 name,
13 profilePic,
14 });
15}

In combination with the anonymous authentication, every client can create its own user or retrieve the stored user-data for its own generated id:

1export async function getOrCreateAnonymousUser() {
2 const anonymous = (await auth(app).signInAnonymously()).user;
3
4 let dbUser = await getUser(anonymous.uid);
5
6 if (!dbUser) {
7 await writeUserData(anonymous.uid, "", "");
8 dbUser = await getUser(anonymous.uid);
9 }
10
11 return dbUser;
12}

To observe changing data is a little more complicated. Besides providing the callback to handle update you have to provide some teardown logic. Like registered event listeners you can remove a callback by calling .off(event_type, callback) on the data-ref.

Creating an observable from the users collections then looks like this:

1export function usersObservable() {
2 return new Observable((observer) => {
3 const callback = (dataSnapshot) => {
4 const usersJson = dataSnapshot.toJSON() || {};
5
6 const userArray = Object.keys(usersJson).map(
7 (userId) => usersJson[userId],
8 );
9
10 observer.next(userArray);
11 };
12
13 // notify observer on value changes
14 database(app).ref(USERS_REF_NAME).on("value", callback);
15 // return unsubscribe function
16 return () => {
17 database(app).ref(USERS_REF_NAME).off("value", callback);
18 };
19 });
20}

The constructed observable emits a new value (array of users), each time the collection in the database changes.

The complete implementation of the chat logic is available in the chat-app-3 repository.

Tasks:

  • checkout the chat-app-3 repository (don't forget to npm install)
  • get familiar with the Login component
  • get familiar with the firebase logic
  • extend the users data-model with a last-seen flag (update the user every time when there is some relevant action in the app)
  • show a list of all registered users ordered by the time they were last seen
The AI-generated image depicts a futuristic, tech-themed workspace filled with servers, monitors displaying code, and various tech gadgets. A glowing orb sits atop a central server rack. The scene is adorned with symbols resembling atoms and tech logos, creating a high-tech, sci-fi atmosphere.

Project WebApp — React on the server and the JAMstack

Learn how to render React components on the server using react-dom/server and frameworks like Next.js. This guide also explores the JAMstack architecture, highlighting tools such as Gatsby for creating static sites with dynamic capabilities.

Mailing List

If you want to receive updates on new posts, leave your email below.