Search code examples
firebasefirebase-realtime-databasejestjssveltecommonjs

firebase.database.ServerValue.TIMESTAMP : database is undefined


It's been days and I still can't figure out why firebase.database is undefined.

chat.js file content

const firebase = require('firebase');
require('firebase/database');

exports.sendMessage = (firebaseRtDb, uid, roomPath, message) => firebaseRtDb.ref(`${roomPath}/messages`).push().set({
  participant: uid,
  date: firebase.database.ServerValue.TIMESTAMP,
  message,
});

chat.spec.js extract

const firebase = require('@firebase/testing');
const { sendMessage } = require('./chat');

const getRtDb = async (projectId, databaseName, auth) => {
  const app = firebase.initializeTestApp(
    {
      projectId,
      databaseName,
      auth,
    },
  );
  const adminApp = firebase.initializeAdminApp({ databaseName });
  const adminDb = adminApp.database();
  await firebase
    .loadDatabaseRules({
      databaseName,
      rules: JSON.stringify(rules),
    });
  const db = app.database();

  return [db, adminDb];
};

let db = null;
let adminDb = null;
const myUid = 'lul';

beforeEach(async () => {
  const [rtDb, rtAdminDb] = await getRtDb('quickChat', 'quickChat', { uid: myUid });
  db = rtDb;
  adminDb = rtAdminDb;
});

afterEach(async () => adminDb.ref('/').set(null));

it('Can write to chat', async () => {
  const roomPath = 'chatsRooms/room1';
  await adminDb.ref(roomPath).set({
    participants: {
      [myUid]: true,
    },
  });
  return firebase.assertSucceeds(sendMessage(db, myUid, roomPath, 'lol'));
});

I tried replacing const firebase = require('firebase'); by onst firebase = require('firebase/app'); and with and without require('firebase/database');.

With code as is in this post, my IDE recognise firebase.database.ServerValue.TIMESTAMP. But Jest test fails. I started the project using npx degit sveltejs/template my-svelte-project.

Jest output

● Chat › Participants › Can write to chat

    TypeError: Cannot read property 'ServerValue' of undefined

      4 | exports.sendMessage = (firebaseRtDb, uid, roomPath, message) => firebaseRtDb.ref(`${roomPath}/messages`).push().set({
      5 |   participant: uid,
    > 6 |   date: firebase.database.ServerValue.TIMESTAMP,
        |                           ^
      7 |   message,
      8 | });
      9 | 

      at sendMessage (src/lib/chat.js:6:27)
      at Object.<anonymous> (src/lib/chat.spec.js:56:38)

package.json

{
  "name": "svelte-app",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "sirv public",
    "test": "jest --detectOpenHandles",
    "test:watch": "jest --watchAll",
    "test:ci": "jest --runInBand"
  },
  "devDependencies": {
    "@firebase/testing": "^0.20.11",
    "@rollup/plugin-commonjs": "^16.0.0",
    "@rollup/plugin-node-resolve": "^10.0.0",
    "eslint": "^7.16.0",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jest": "^24.1.3",
    "eslint-plugin-promise": "^4.2.1",
    "jest": "^26.6.3",
    "rollup": "^2.3.4",
    "rollup-plugin-css-only": "^3.1.0",
    "rollup-plugin-livereload": "^2.0.0",
    "rollup-plugin-svelte": "^7.0.0",
    "rollup-plugin-terser": "^7.0.0",
    "svelte": "^3.0.0"
  },
  "dependencies": {
    "firebase": "^8.2.1",
    "sirv-cli": "^1.0.0"
  }
}

EDIT 1 : forgot to add getRtDb() definition


Solution

  • The dependency @firebase/testing was the cause. It is deprecated and I had to replace it by @firebase/rules-unit-testing.

    I also switched to Typescript and made the import as follow:

    chat.spec.ts

    import * as firebase from '@firebase/rules-unit-testing';
    
    import rules from '../../database.rules.json';
    import { sendMessage } from './chat';
    

    chat.ts

    import firebase from 'firebase/app';
    import 'firebase/database';