Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion functions/android.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,12 @@ module.exports = {

androidNotificationKeys.forEach((key) => {
if (Object.hasOwn(req.body.data, key)) {
payload.data[key] = String(req.body.data[key]);
const v = req.body.data[key];
// FCM data values must be strings. For arrays/objects (e.g. when the
// calling integration's template engine auto-parses a JSON-string
// back into a list), String(value) produces "[object Object]" which
// the receiving app then can't decode as JSON. Stringify properly.
payload.data[key] = (v !== null && typeof v === 'object') ? JSON.stringify(v) : String(v);
Comment on lines +116 to +121
}
});
}
Expand Down
7 changes: 5 additions & 2 deletions functions/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ function handleError(req, res, payload = {}, step, incomingError, shouldExit = t
incomingError = new Error(incomingError);
}

// Handle Firebase Messaging errors with appropriate status codes
if (incomingError.code?.startsWith('messaging/')) {
// Handle Firebase Messaging errors with appropriate status codes.
// `code` can be a non-string (e.g. numeric HTTP status from a network failure
// before reaching FCM); without the type guard, .startsWith throws and masks
// the underlying error.
if (typeof incomingError.code === 'string' && incomingError.code.startsWith('messaging/')) {
const errorCode = incomingError.code.replace('messaging/', '');

// For specific token errors, skip reporting and return immediately
Expand Down
Loading