I am facing a persistent 404 Not Found error when trying to send a notification from a 2nd Gen Node.js Cloud Function using admin.messaging().sendToTopic().
The baffling part is that I can successfully send test notifications to my live app from the Firebase Console's campaign tool. This proves my client-side Flutter app, google-services.json file, and the app signing keys (SHA-1) are all configured correctly. The issue is strictly isolated to the server-side execution environment of my Cloud Function.
Here is the function code for addJanazah:
export const addJanazah = onCall(async (request) => {
// ... (code to validate request and write to Firestore) ...
// This part works successfully.
// This is the part that fails:
try {
const payload = {
notification: {
title: `New Janazah`,
body: `A new Janazah has been scheduled.`
},
data: { 'screen': 'map_page' }
};
console.log("Attempting to send notification with payload:", JSON.stringify(payload));
await getMessaging().sendToTopic('new_janazah_notifications', payload);
console.log("Successfully sent notification.");
} catch (messagingError) {
// This is the error I am seeing in my production logs:
console.warn("Warning: Could not send notification.", messagingError);
}
return { success: true };
});
and here is the exact error log from Google cloud logs:
Warning: Could not send notification. FirebaseMessagingError: An unknown server error was returned. Raw server response: "<HTML>
<HEAD>
<TITLE>Not Found</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<!-- GSE Default Error -->
<H1>Not Found</H1>
<H2>Error 404</H2>
</BODY>
</HTML>
". Status code: 404.
at createFirebaseError (/workspace/node_modules/firebase-admin/lib/messaging/messaging-errors-internal.js:57:12)
at /workspace/node_modules/firebase-admin/lib/messaging/messaging-api-request-internal.js:82:75
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async file:///workspace/index.js:180:9
at async /workspace/node_modules/firebase-functions/lib/common/providers/https.js:467:26 {
errorInfo: {
code: 'messaging/unknown-error',
message: 'An unknown server error was returned. Raw server response: "<HTML>\n' +
'<HEAD>\n' +
'<TITLE>Not Found</TITLE>\n' +
'</HEAD>\n' +
'<BODY BGCOLOR="#FFFFFF" TEXT="#000000">\n' +
'<!-- GSE Default Error -->\n' +
'<H1>Not Found</H1>\n' +
'<H2>Error 404</H2>\n' +
'</BODY>\n' +
'</HTML>\n' +
'". Status code: 404.'
},
codePrefix: 'messaging'
}
Exhaustive List of Troubleshooting Steps Already Taken:
I have meticulously checked every standard configuration, and the error still persists. I have verified:
APIs are Enabled: Both the Firebase Cloud Messaging API and the Cloud Pub/Sub API are confirmed to be "Enabled" in the Google Cloud Console for my firebase project. I have also tried disabling and then re-enabling both APIs to force a re-provisioning, with no change.
IAM Permissions: I have granted Owner, Firebase Admin, and Pub/Sub Publisher roles to both of the following service accounts:
The function's runtime identity (Default Compute Service Account): [email protected]
The Firebase Admin SDK Service Account: [email protected]
API Keys: I have confirmed the API keys for the project are not restricted in a way that would block these services.
I have 1 default API key (the one created automatically by firebase for android and that is configured in google-services.json
and another specific API key that I created for Maps SDK and configured in AndroidManifest.xml this way
<meta-data android:name="com.google.android.geo.API_KEY"
android:value=XXXX"/>
- I made sue the app signing key certificate from Play cconsole integrity is added to the fingerprints of the Android app configuration in firebase.
My Question:
Given that all user-configurable settings appear to be correct (client-side config, APIs, IAM permissions for both relevant service accounts), this strongly points to an internal service provisioning or networking issue within my Google Cloud project. The Cloud Functions environment seems unable to resolve the Pub/Sub endpoint that sendToTopic relies on.
Has anyone encountered this specific 404 error from sendToTopic after having already verified all of the above steps? Is there a known, deeper-level configuration or project state that could cause this?
sendToTopicin Google's documentation.