Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Edge runtime v1.2.18 fails to import firebase-admin with Identifier '__f$' has already been declared #82

Closed
evelant opened this issue May 5, 2023 · 13 comments
Labels
C-bug Category: something isn't working

Comments

@evelant
Copy link

evelant commented May 5, 2023

Bug report

  • [ X] I confirm this is a bug with Supabase, not with my own application.
  • [X ] I confirm I have searched the Docs, GitHub Discussions, and Discord.

Describe the bug

I upgraded from Supabase cli v1.49.4 to 1.55.1. After doing so my edge function that imports firebase-admin no longer runs, it crashes with Identifier '__f$' has already been declared. This function worked fine on supabase cli 1.49.4 (not sure which edge-runtime version that is).

To Reproduce

  1. Run an edge fn with import firebase from "https://esm.sh/[email protected]?bundle&target=deno&no-check"
  2. Call the function, observe crash
worker thread panicked Uncaught SyntaxError: Identifier '__f$' has already been declared
    at https://esm.sh/v119/[email protected]/deno/firebase-admin.bundle.mjs:2:1611
 Error: channel closed
     at async UserWorker.fetch (ext:sb_user_workers/user_workers.js:50:21)
     at async Server.<anonymous> (file:///home/deno/main/index.ts:102:16)
     at async Server.#respond (https://deno.land/[email protected]/http/server.ts:220:24)

Expected behavior

Imports that previously worked should continue working

Screenshots

N/A

System information

  • OS: [e.g. macOS, Windows]
  • Browser (if applies) [e.g. chrome, safari]
  • Version of supabase-js: [e.g. 6.0.2]
  • Version of Node.js: [e.g. 10.10.0]

Additional context

This worked fine with Supabase cli v1.49.4. I've deleted deno.lock and all deno cache files and the issue persists. If I switch back to cli 1.49.4 it works again but then I can't import local code since that feature was just released.

@evelant evelant added the C-bug Category: something isn't working label May 5, 2023
@evelant
Copy link
Author

evelant commented May 5, 2023

Ah it seems I'm still blocked by #44 anyway, the edge runtime still becomes completely unresponsive after any error.

@andreespirela
Copy link
Collaborator

I think this could've been fixed by #74. I just ran the following piece of code in latest main

import firebase from "https://esm.sh/[email protected]?bundle&target=deno&no-check"

console.log(`Firebase`, firebase);

and it worked properly, logging:

Firebase <ref *1> hn {
  __esModule: true,
  credential: {
    cert: [Function: Nd],
    refreshToken: [Function: _d],
    applicationDefault: [Function: Id]
  },
  SDK_VERSION: "11.5.0",
  Promise: [Function: Promise],
  INTERNAL: cn { appStore: Hr { appStore: Map {} } },
  default: [Circular *1]
}

It also seems some of the issues with the module loader is solved. CC @laktek

@andreespirela
Copy link
Collaborator

@evelant We just rolled out a CLI update. Could you check if you experience the same with 1.61.1 ?

Thanks!

@evelant
Copy link
Author

evelant commented May 17, 2023

@andreespirela yes this error still happens with 1.61.2 unfortunately.

@laktek
Copy link
Contributor

laktek commented May 17, 2023

@evelant Do you call a specific function from firebase import? I tried importing and console.log(firebase). That worked.

@evelant
Copy link
Author

evelant commented May 17, 2023

@laktek I only use the firebase SDK in development so I can auth against the firebase emulators. Here is the totality of the code that uses the firebase SDK.

let hasInitialized = false
/**
 * call firebase.initializeApp with credentials so we can verify the firebase auth token is legit
 */
const initFirebaseApp = async () => {
    const firebase = (await import("https://esm.sh/[email protected]?bundle&target=deno&no-check")).default
    if (hasInitialized) return firebase
    hasInitialized = true
    if (Deno.env.has("FIRESTORE_EMULATOR_HOST") && Deno.env.has("FIREBASE_AUTH_EMULATOR_HOST")) {
        console.log(`initializing firebase app with emulators`)
        firebase.initializeApp({ projectId: Deno.env.get("FIREBASE_PROJECT_ID") })
    } else {
        const serviceAccount = JSON.parse(Deno.env.get("FIREBASE_SERVICE_ACCOUNT") || "{}")
        console.log(`initializing firebase app ${serviceAccount.project_id}`)
        try {
            const credential = firebase.credential.cert(serviceAccount)
            //@ts-ignore types don't work correctly with deno
            const firebaseConfig: firebase.AppOptions = {
                projectId: serviceAccount.project_id,
                credential,
                databaseURL: serviceAccount.database_url,
            }
            firebase.initializeApp(firebaseConfig)
        } catch (err: any) {
            console.error(`Error initializing firebase app`, err)
        }
    }
    return firebase
}

const verifyFirebaseEmulatorToken = async (token: string): Promise<jose.JWTPayload | undefined> => {
    const firebase = await initFirebaseApp()
    try {
        const v = await firebase.auth().verifyIdToken(token)
        return v
    } catch (err: unknown) {
        console.error(`Error verifying firebase emulator token`, err)
    }
    return undefined
}

@laktek
Copy link
Contributor

laktek commented May 17, 2023

Thanks for the full example. The firebase import seems to work for me. I do get an error on initialization though, but that's because I do not have a valid value set for FIREBASE_SERVICE_ACCOUNT.

I wonder if the error occurs because of some issue with firebase module that's already cached. Can you try bumping up the version of it to the latest? which is 11.8.0 (https://www.npmjs.com/package/firebase-admin)

@evelant
Copy link
Author

evelant commented May 17, 2023

@laktek I already tried clearing deno cache. Updating to latest firebase admin also does not help.

In this case you can ignore the branch using FIREBASE_SERVICE_ACCOUNT, I don't actually use that anymore. The failing case is with

FIRESTORE_EMULATOR_HOST='host.docker.internal:8080'
FIREBASE_AUTH_EMULATOR_HOST='host.docker.internal:9099'

and running just the firebase auth emulator with firebase emulators:start --only auth

@laktek
Copy link
Contributor

laktek commented May 17, 2023

BTW, does it work with Deno CLI? deno run --allow-env --allow-net --no-npm YOUR_FUNC.ts

@evelant
Copy link
Author

evelant commented May 18, 2023

@laktek if I try to run it locally with those permissions Deno asks for permission to read files

 Deno requests read access to "/PATH/TO/MY/HOME/.config/gcloud/application_default_credentials.json".
├ Requested by `Deno.readFileSync()` API.

Could that cause the crash on the edge runtime? Looks like the google APIs attempt to read credentials from the FS by default.

@laktek
Copy link
Contributor

laktek commented May 18, 2023

That's the issue - Edge Functions don't have file system access when hosted. Edge Runtime also mimics this behavior locally. If this function is something you'd only need for local development but not in production, maybe best way would be to run it with deno run with necessary permissions.

@evelant
Copy link
Author

evelant commented May 18, 2023 via email

@laktek
Copy link
Contributor

laktek commented May 18, 2023

Yep, we will look into it. I'll close this ticket for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants