fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Firebase Admin RTDB Works Locally But Not in Deno Deploy

Open azroberts8 opened this issue 1 year ago • 2 comments

Context / Setup

I am using Firebase Admin in Fresh 1.6.8 to fetch and render values from a Firebase realtime database server-side. My project is deployed on Deno Deploy with the Fresh (with Build step) preset and the contents of my Firebase service account file are stored in the FIREBASE_ADMIN_KEY environment variable in Deno Deploy.

Goal

I would like to use Firebase Admin server-side at runtime but do not want the Firebase initialization or related code executed at build time.

Problem

My project works locally with the code provided below however when I deploy, the build process fails with the following error:

warning: Packages contained npm lifecycle scripts (preinstall/install/postinstall) that were not executed.
    This may cause the packages to not work correctly. To run them, use the `--allow-scripts` flag with `deno cache`
    (e.g. `deno cache --allow-scripts=pkg1,pkg2 <entrypoint>`):
      npm:[email protected]
error: Uncaught (in promise) Error: Service account object must contain a string "project_id" property.
    at new ServiceAccount (file:///home/runner/work/Stampede-v2/Stampede-v2/node_modules/.deno/[email protected]/node_modules/firebase-admin/lib/app/credential-internal.js:145:19)
    at new ServiceAccountCredential (file:///home/runner/work/Stampede-v2/Stampede-v2/node_modules/.deno/[email protected]/node_modules/firebase-admin/lib/app/credential-internal.js:70:15)
    at cert (file:///home/runner/work/Stampede-v2/Stampede-v2/node_modules/.deno/[email protected]/node_modules/firebase-admin/lib/app/credential-factory.js:103:54)
    at file:///home/runner/work/Stampede-v2/Stampede-v2/utilities/firebase.ts:6:15
Error: Process completed with exit code 1.

This issue occurs as a result of FIREBASE_ADMIN_KEY not being accessible in the build environment but this also signifies that the build process is attempting to initialize a connection to Firebase. I only want the connection to initialize in the deployed runtime environment not in the build environment.

Code

./firebase.ts

import { initializeApp, cert, ServiceAccount } from "npm:firebase-admin/app";
import { getDatabase } from 'npm:firebase-admin/database';

const firebaseCreds: ServiceAccount = JSON.parse(Deno.env.get("FIREBASE_ADMIN_KEY") || "{}");
const firebase = initializeApp({
  credential: cert(firebaseCreds),
  databaseURL: "https://my-database-default-rtdb.firebaseio.com/"
});
const database = getDatabase(firebase);

export { database };

./routes/index.tsx

import { database } from "../firebase.js";

export const handler: Handlers = {
  async GET(_req, ctx) {
    const ref = database.ref("/test");
    const value = (await ref.get()).val();
    return ctx.render(value);
  }
}

export default function Home(props: PageProps) {
  return (
    <div>
      { props.data }
    </div>
  );
}

azroberts8 avatar Sep 18 '24 21:09 azroberts8