Database
Common use cases
Core
Initialization
import { getDatabase } from "firebase/database";
const database = getDatabase();
Connect to the Emulator Suite
import { getDatabase, useDatabaseEmulator } from "firebase/database";
const db = getDatabase();
if (location.hostname === "localhost") {
// Point to the RTDB emulator running on localhost.
useDatabaseEmulator(db, "localhost", 9000);
}
Flush the data in the Emulator Suite
import { getDatabase, ref, set } from "firebase/database";
// With a database Reference, write null to clear the database.
const db = getDatabase();
set(ref(db), null);
Sharding
import { initializeApp } from "firebase/app";
import { getDatabase } from "firebase/database";
const app1 = initializeApp({
databaseURL: "https://testapp-1234-1.firebaseio.com"
});
const app2 = initializeApp({
databaseURL: "https://testapp-1234-2.firebaseio.com"
}, 'app2');
// Get the default database instance for an app1
const database1 = getDatabase(app1);
// Get a database instance for app2
const database2 = getDatabase(app2);
Reading and writing
Create a new object
import { getDatabase, ref, set } from "firebase/database";
function writeUserData(userId, name, email, imageUrl) {
const db = getDatabase();
set(ref(db, 'users/' + userId), {
username: name,
email: email,
profile_picture : imageUrl
});
}
Check for a successful server write
import { getDatabase, ref, set } from "firebase/database";
const db = getDatabase();
set(ref(db, 'users/' + userId), {
username: name,
email: email,
profile_picture : imageUrl
})
.then(() => {
// Data saved successfully!
})
.catch((error) => {
// The write failed...
});
Listen for realtime updates
import { getDatabase, ref, onValue} from "firebase/database";
const db = getDatabase();
const starCountRef = ref(db, 'posts/' + postId + '/starCount');
onValue(starCountRef, (snapshot) => {
const data = snapshot.val();
updateStarCount(postElement, data);
});
Read data one time
import { getDatabase, ref, onValue } from "firebase/database";
import { getAuth } from "firebase/auth";
const db = getDatabase();
const auth = getAuth();
const userId = auth.currentUser.uid;
return onValue(ref(db, '/users/' + userId), (snapshot) => {
const username = (snapshot.val() && snapshot.val().username) || 'Anonymous';
// ...
}, {
onlyOnce: true
});
Fan out an object to multiple locations
function writeNewPost(uid, username, picture, title, body) {
const db = getDatabase();
// A post entry.
const postData = {
author: username,
uid: uid,
body: body,
title: title,
starCount: 0,
authorPic: picture
};
// Get a key for a new Post.
const newPostKey = push(child(ref(db), 'posts')).key;
// Write the new post's data simultaneously in the posts list and the user's post list.
const updates = {};
updates['/posts/' + newPostKey] = postData;
updates['/user-posts/' + uid + '/' + newPostKey] = postData;
return update(ref(db), updates);
}
Run a transaction
import { getDatabase, ref, runTransaction } from "firebase/database";
function toggleStar(uid) {
const db = getDatabase();
const postRef = ref(db, '/posts/foo-bar-123');
runTransaction(postRef, (post) => {
if (post) {
if (post.stars && post.stars[uid]) {
post.starCount--;
post.stars[uid] = null;
} else {
post.starCount++;
if (!post.stars) {
post.stars = {};
}
post.stars[uid] = true;
}
}
return post;
});
}
Lists of data
Add a new value to a list
import { getDatabase, ref, push, set } from "firebase/database";
// Create a new post reference with an auto-generated id
const db = getDatabase();
const postListRef = ref(db, 'posts');
const newPostRef = push(postListRef);
set(newPostRef, {
// ...
});
Listen to list updates in realtime
import { getDatabase, ref, onValue } from "firebase/database";
const db = getDatabase();
const dbRef = ref(db, '/a/b/c');
onValue(dbRef, (snapshot) => {
snapshot.forEach((childSnapshot) => {
const childKey = childSnapshot.key;
const childData = childSnapshot.val();
// ...
});
}, {
onlyOnce: true
});
Listen to child updates in realtime
import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database";
const db = getDatabase();
const commentsRef = ref(db, 'post-comments/' + postId);
onChildAdded(commentsRef, (data) => {
addCommentElement(postElement, data.key, data.val().text, data.val().author);
});
onChildChanged(commentsRef, (data) => {
setCommentValues(postElement, data.key, data.val().text, data.val().author);
});
onChildRemoved(commentsRef, (data) => {
deleteComment(postElement, data.key);
});
Order a list by a child property
import { getDatabase, ref, query, orderByChild } from "firebase/database";
import { getAuth } from "firebase/auth";
const db = getDatabase();
const auth = getAuth();
const myUserId = auth.currentUser.uid;
const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));
Limit the results of a list
import { getDatabase, ref, query, limitToLast } from "firebase/database";
const db = getDatabase();
const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));
Connectivity
Detect connection state
import { getDatabase, ref, onValue } from "firebase/database";
const db = getDatabase();
const connectedRef = ref(db, ".info/connected");
onValue(connectedRef, (snap) => {
if (snap.val() === true) {
console.log("connected");
} else {
console.log("not connected");
}
});
Write data after a client loses connection
import { getDatabase, ref, onDisconnect } from "firebase/database";
const db = getDatabase();
const presenceRef = ref(db, "disconnectmessage");
// Write a string when this client loses connection
onDisconnect(presenceRef).set("I disconnected!");
Handle onDisconnect errors
onDisconnect(presenceRef).remove().catch((err) => {
if (err) {
console.error("could not establish onDisconnect event", err);
}
});
Cancel onDisconnect events
const onDisconnectRef = onDisconnect(presenceRef);
onDisconnectRef.set("I disconnected");
// some time later when we change our minds
onDisconnectRef.cancel();
Estimate clock-skew
import { getDatabase, ref, onValue } from "firebase/database";
const db = getDatabase();
const offsetRef = ref(db, ".info/serverTimeOffset");
onValue(offsetRef, (snap) => {
const offset = snap.val();
const estimatedServerTimeMs = new Date().getTime() + offset;
});
Manage user presence
import { getDatabase, ref, onValue, push, onDisconnect, set, serverTimestamp } from "firebase/database";
// Since I can connect from multiple devices or browser tabs, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
const db = getDatabase();
const myConnectionsRef = ref(db, 'users/joe/connections');
// stores the timestamp of my last disconnect (the last time I was seen online)
const lastOnlineRef = ref(db, 'users/joe/lastOnline');
const connectedRef = ref(db, '.info/connected');
onValue(connectedRef, (snap) => {
if (snap.val() === true) {
// We're connected (or reconnected)! Do anything here that should happen only if online (or on reconnect)
const con = push(myConnectionsRef);
// When I disconnect, remove this device
onDisconnect(con).remove();
// Add this device to my connections list
// this value could contain info about the device or a timestamp too
set(con, true);
// When I disconnect, update the last time I was seen online
onDisconnect(lastOnlineRef).set(serverTimestamp());
}
});
Set a server timestamp
import { getDatabase, ref, onDisconnect, serverTimestamp } from "firebase/database";
const db = getDatabase();
const userLastOnlineRef = ref(db, "users/joe/lastOnline");
onDisconnect(userLastOnlineRef).set(serverTimestamp());