Hello ![]()
I am trying to write and deploy my first Netlify edge function. The goal is to send notifications via Firebase Cloud Messaging. I created a send-notification.js file that requires two npm dependencies.
When running netlify dev everything works fine.
However, when i deploy my app the build fails due to the external dependencies:
3:38:33 PM: Edge Functions bundling 3:38:33 PM: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 3:38:33 PM: β 3:38:33 PM: Packaging Edge Functions from netlify/edge-functions directory: 3:38:33 PM: - send-notifications 3:38:34 PM: error: Uncaught (in promise) Error: Relative import path firebase-admin/messaging not prefixed with / or ./ or ../ and not in import map from file:///root/netlify/edge-functions/send-notifications.js 3:38:34 PM: const ret = new Error(getStringFromWasm0(arg0, arg1)); 3:38:34 PM: ^ 3:38:34 PM: at __wbg_new_15d3966e9981a196 (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm.generated.js:417:19) 3:38:34 PM: at <anonymous> (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm_bg.wasm:1:93412) 3:38:34 PM: at <anonymous> (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm_bg.wasm:1:1499594) 3:38:34 PM: at <anonymous> (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm_bg.wasm:1:1938165) 3:38:34 PM: at __wbg_adapter_40 (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm.generated.js:231:6) 3:38:34 PM: at real (file:///opt/buildhome/node-deps/node_modules/@netlify/edge-bundler/deno/vendor/deno.land/x/eszip@v0.40.0/eszip_wasm.generated.js:215:14) 3:38:34 PM: at eventLoopTick (ext:core/01_core.js:182:11) 3:38:34 PM: β 3:38:34 PM: Bundling of edge function failed 3:38:34 PM: ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ 3:38:34 PM: β 3:38:34 PM: Error message 3:38:34 PM: It seems like you're trying to import an npm module. This is only supported via CDNs like esm.sh. Have you tried 'import mod from https://esm.sh/firebase-admin/messaging'? β 3:38:34 PM: Error location 3:38:34 PM: While bundling edge function 3:38:34 PM: β 3:38:34 PM: Resolved config 3:38:34 PM: build: 3:38:34 PM: command: npm install 3:38:34 PM: commandOrigin: ui 3:38:34 PM: edge_functions: /opt/build/repo/netlify/edge-functions 3:38:34 PM: publish: /opt/build/repo 3:38:34 PM: publishOrigin: ui 3:38:34 PM: functionsDirectory: /opt/build/repo/netlify/edge-functions 3:38:34 PM: redirects: 3:38:35 PM: Build failed due to a user error: Build script returned non-zero exit code: 2 3:38:35 PM: Failing build: Failed to build site 3:38:35 PM: Finished processing build request in 13.933s I also tried to import the dependencies via CDN but without success. Ideally i would like it to work with the dependencies defined in my package.json.
For anyone wondering this is my project setup:
netlify.toml
[build] external_node_modules = ["firebase-admin", "dotenv"] functions = "netlify/edge-functions/" [[redirects]] from = "/api/*" to = "/.netlify/functions/:splat" status = 200 My netlify edge function:
netlify/edge-functions/send-notifications.js
import { initializeApp, applicationDefault } from 'firebase-admin/app'; import dotenv from 'dotenv'; import { getMessaging } from 'firebase-admin/messaging'; dotenv.config(); const credentialsPath = process.env.GOOGLE_APPLICATION_CREDENTIALS; console.log(credentialsPath); initializeApp({ credential: applicationDefault(), projectId: 'shared-list-preview', }); export async function handler(event, context) { console.log('Send notifications called') if (event.httpMethod === undefined && event.httpMethod !== 'POST') { return { statusCode: 400, body: JSON.stringify({ error: 'Only post requests allowed.' }), }; } else { const requestBody = JSON.parse(event.body) if (isEmpty(requestBody.title) || isEmpty(requestBody.text) || isEmpty(requestBody.fcmTokens)) { return { statusCode: 400, body: JSON.stringify({ error: 'Body must contain title, text and fcmTokens.' }), }; } } const requestBody = JSON.parse(event.body) const message = { notification: { title: requestBody.title, body: requestBody.text, }, tokens: requestBody.fcmTokens } try { const batchResponse = await getMessaging().sendEachForMulticast(message); // Return a success response if (batchResponse.failureCount === 0) { const successMsg = `Successfully sent ${batchResponse.successCount} message(s)` console.log(successMsg) return { statusCode: 200, body: JSON.stringify({ message: successMsg }), }; } else { const failureMsg = `Failure - Was able to sent ${batchResponse.successCount}/${batchResponse.failureCount} message(s)` console.log(failureMsg) return { statusCode: 500, body: JSON.stringify({ message: failureMsg, responses: batchResponse.responses }), } } } catch (error) { console.log('Error sending message:', error); return { statusCode: 500, body: JSON.stringify({ error: error.message }), }; } } function isEmpty(str) { return (!str || str.length === 0 ); } (I get warnings locally, if anyone knows how to get rid of them I would be happy to know:)
β Loaded edge function send-notifications β Failed to run Edge Function send-notifications: TypeError: Relative import path "firebase-admin/messaging" not prefixed with / or ./ or ../ and not in import map from "my-project/netlify/edge-functions/send-notifications.js" at my-project/netlify/edge-functions/send-notifications.js:3:30 at async file:///user/AppData/Local/Temp/tmp-31204-qKAJa6073fym/dev.js:7:35 { code: "ERR_MODULE_NOT_FOUND" I would gladly appreciate any hints! Thank you so much ![]()