I have an application where I need to generate push notifications to individual users based on application permissions. I have an Angular frontend using Firebase Cloud Messaging to generate and store
token for the user to my server via an API call. The web front end is the only implementation, so in the firebase console it has a single Web App and no IOS or Android config. I’ve set up FirebaseAdmin SDK for C# according to the Official Documentation and an attempting to generate multicast messages to the device tokens Ive selected based on a query. When I catch it in debugger it shows that the call is receiving failure response "Auth error from APNS or Web Push Service". My Implementation looks like this on the Server side:
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromFile("path/to/refreshToken.json"),
ProjectId = settings.ProjectId,
});
var message = new MulticastMessage()
{
Tokens = firebaseTokens,
Data = new Dictionary<string, string>()
{
{ "Message", body },
{ "Title", title },
},
};
var result = await FirebaseMessaging.DefaultInstance.SendEachForMulticastAsync(message);
The json token I am using is for a service account that has Firebase Service Management Service Agent. I thought maybe its a permissions issue but I tried a few different combinations and the result seems the same. Any ideas are appreciated, I’ve been stuck on this for a while.
Update: I tried generating new key for the FirebaseAdmin account and switching to that account instead of service account and I still get the same error.
Update: After comment suggestion I have tried catching the defaultInstance in debugger. I had tried before and upon first glance it appeared to be instantiated but I took a closer look and many of the properties look to be null. It is getting the App name but perhaps the file isn’t being targeted correctly. Will update once I can confirm.
2
Answers
Upon further examination I found that the token permission was "denied". To resolve this issue I rewrote the handling for expired tokens on the client. This looks something like this:
In conjunction with that I rewrote the server side so that if it detects a token is invalid it will flag a Boolean value to mark it as invalidated and "soft-delete" it.
Can you try getting the path like this and pass the fullPath to GoogleCredential.FromFile ? Also please check if FirebaseMessaging.DefaultInstance is null. In C# sdk, DefaultInstance is static and you should only be creating it if it is null to protect yourself from some very hard to find bugs down the path and to avoid any memory leakage issues.