My app is implemented in React Native and is using Firebase for notifications. We have webhooks on the web app that are triggered on certain events. Those webhooks then send a request to the respective Firebase Cloud Function. With information from the request's header they get the topic they must send the notification to; from the request's body it gathers the information to be sent as data to the device. They are sent as data notifications only, the handler (using the React Native FCM API) then shows a local notification already translated with i18n using the react-native-push-notifications package. Everything works fine until I hit the weird situation described below.
Everything was doing alright both on Android and iOS until I launched the app on Test Flight for internal testing and then it stopped working after some time on iOS. Eventually, I noticed that when more than one iPhone subscribed to the same topic it eventually lead to inconsistencies in the delivery of the data notifications. The first iPhone to subscribe to the topic usually worked, the others didn't, the first one most of the time eventually stopped working as well or sometimes it just kept working while the others still didn't. I used the Firebase Console to send some test notification to the subscribed devices and it they actually received it. I then changed my Cloud Functions' code to avoid sending any data and just send some example body and title and it turns out the problem was here. As soon as I send something through the data field in the admin.messaging.Message object to be sent as argument to the admin.messaging().send method, they aren't received by the iPhone devices subscribed to the topic (or it's received by one or two max, the first ones to currently subscribe to the topic. But they usually stop receiving them after a while as well).
This is really really weird and being so inconsistent makes it practically impossible to debug with my current knowledge. Some things to keep in mind:
- All Android devices still receive the notifications without a problem
- I've watched the iPhone's console through Xcode to see if there was some error when processing the notification, in case they were actually getting the notification but they it failed before it was shown to the user. But nothing is logged by the SpringBoard process, making me conclude the notifications aren't actually getting to the device
- I've manually sent notifications with cURL to APNs (with this guide). They were received fine
- All notifications without data, regardless of the iOS specific apn headers, payload, etc, are received
What can be the cause of the problem? Or there's something in my code causing this strange behavior (which I doubt, since it works fine on Android and works fine in iOS as well on specific scenarios), there's some type of bug on Firebase's side causing some notifications to not be sent or, finally, there's some error on Apple's APNs side causing this. Highly doubt the last one, if the fault lays on any exterior factor it probably should be on Firebase's handling of topics.
Really would appreciate some help. Thanks in advance. Sorry If I didn't gave enough information, I actually never had the need to do a question on Stack Overflow. I'll leave below an example of a cloud function as well.
exports.orderPending = functions
.region("europe-west2")
.https.onRequest((req, res) => {
if (req.method == "POST") {
res.status("200").send("Webhook successful");
const topic = req.headers["code"];
const message = {
data: {
id: JSON.stringify(req.body.order.id),
event: "orderPending",
order: JSON.stringify(req.body.order),
},
topic,
android: {
priority: "high",
},
apns: {
payload: {
aps: {
contentAvailable: true,
},
},
headers: {
"apns-push-type": "background",
"apns-priority": "5",
"apns-topic": "APP BUNDLE ID HERE",
},
},
};
functions.logger.log(req.body.order.id);
functions.logger.log(topic);
admin.messaging().send(message)
.then((response) => {
console.log("Successfully sent message: ", response);
})
.catch((error) => {
console.log("Error sending message: ", error);
});
}
});