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 ![]()