javascriptfirebasefirebase-realtime-databasemodular

Firebase web modular API get() and dbRef


I am migrating from the Firebase namespaced to modular API. There is one detail I do not fully understand.

I have replaced the once() call with get(), but it's the database reference usage that confuses me. I have already initiated and exposed the database in a separate file using.

import { initializeApp } from "firebase/app";
import { getDatabase } from "firebase/database";

const firebaseConfig = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.FIREBASE_DATABASE_URL,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
};

const app = initializeApp(firebaseConfig);
const database = getDatabase(app);

export { database };

This reference is then used to create database refs.

import { database } from '../firebase/firebase'

const uidRef = ref(database, `${dbPathAccess}/${uid}`);
onValue(uidRef, (mySnapshots) => {
...

However, when using get() I have to use getDatabase() to avoid errors.

import { ref, getDatabase, get, child } from "firebase/database";

const dbRef = ref(getDatabase());
get(child(dbRef, `${dbPathAccess}/${uid}`)).then((mySnapshots) => {

In other words, the below code does not work

import { database } from '../firebase/firebase'

get(child(database, `${dbPathAccess}/${uid}`)).then((mySnapshots) => {

Why is that? They both seems valid to me.

I cannot see any explanation for the behaviour in the documentation -->

https://firebase.google.com/docs/database/web/read-and-write#read_data_once_with_get

EDIT: The error I receive is:

index.esm2017.js:2900 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'pieceNum_')

Upon examination this error originates from

get(child(database, `${dbPathAccess}/${uid}`)).then((mySnapshots) => {

and then gets caught at

function child(parent, path) {
    parent = getModularInstance(parent);
    if (pathGetFront(parent._path) === null) { //<--- THIS LINE
        validateRootPathString('child', 'path', path, false);
    }
    else {

and then finally gets caught here

function pathGetFront(path) {
    if (path.pieceNum_ >= path.pieces_.length) { // <-- THIS LINE
        return null;

EDIT:

The syntax below works, still not sure what the benefit / damage of this usage is though compared to ref(getDatabase());.

get(child(ref(database), `${dbPathAccess}/${uid}`)).then((mySnapshots) => {

Still not sure which way is the preferred / best practice.


Solution

  • The first argument to the get function needs to be a Query (or a DatabaseReference, which extends Query). A Database object is not a Query or DatabaseReference, so it can't be passed as the first argument to get().

    So the correct call is:

    get(ref(database, `${dbPathAccess}/${uid}`))