I am trying to migrate from legacy FCM(Firebase Cloud Messaging) API to the new FCM API V1. For this I have done a few things on the FCM side as per the FCM documentation, I have created the service account, downloaded the JSON file for authenticating requests. My code is in C#, so on C# side, I have made the following changes:
Below is the code that I have written for achieving this:
PersUser persUser = PersUser.GetPersUser();
string pushToken = persUser.PushNotificationToken;
if (persUser != null && !String.IsNullOrEmpty(pushToken))
{
string senderId = string.Empty;
// Load credentials from the JSON key file
GoogleCredential credential;
using (var stream = new FileStream(@"JSON_FILE_PATH", FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped("https://www.googleapis.com/auth/firebase.messaging");
}
string accessToken = String.Empty;
// Obtain an access token
if (credential != null)
{
var token = await credential.UnderlyingCredential.GetAccessTokenForRequestAsync();
accessToken = Convert.ToString(token);
}
senderId = ConfigurationManager.AppSettings["FIREBASESENDERID"];
var httpWebRequest = (HttpWebRequest)System.Net.WebRequest.Create("https://fcm.googleapis.com/v1/projects/myproject-id/messages:send");
httpWebRequest.ContentType = "application/json";
httpWebRequest.Headers.Add(string.Format("Authorization: Bearer {0}", accessToken));
httpWebRequest.Method = "POST";
var body = new object();
body = new
{
token = pushToken,
notification = new
{
title = "Patient Flow",
body = message,
sound = soundFileName
},
data = new
{
type = notificationType
}
};
string jsonPayload = String.Empty;
var serializer = new JavaScriptSerializer();
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = jsonPayload = serializer.Serialize(body);
streamWriter.Write(json);
streamWriter.Flush();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string httpResult = streamReader.ReadToEnd();
if (httpResponse.StatusCode != HttpStatusCode.OK)
{
Logger.Write(TraceTyp.DEBUG, String.Empty, "PushNotificationProcessor.SendNotification", string.Format("Push notification for {0} was not successfully delivered.", httpResponse), String.Empty);
}
}
return true;
}
return false;
When I debug this, I see a 400 Bad request error at:
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
I have also tried the solution suggested in Firebase Cloud Messaging Device Group Management via HTTP v1 auth, but that hasn't helped.
Please suggest what I may be missing here. Where am I possibly going wrong?
The 400 bad request error as we know it mostly has to do with the syntax, which means that the request might be malformed. The reason why I was getting the 400 bad request error was that I was trying to migrate to the new FCM API V1 and the new FCM API accepts a slightly different json payload as opposed to what the legacy FCM API used to accept. The only change that I have done to my code is at the place where I am forming the payload.
This is the payload that I earlier had
body = new {
token = pushToken,
notification = new
{
title = "Patient Flow",
body = message,
sound = soundFileName,
};
data = new
{
type = notificationType
}
};
The updated payload:
body = new {
message = new
{
token = pushToken,
data = new
{
title = "Patient Flow",
body = NotificationMessage,
sound = soundFileName,
notificationType = notificationType
}
}
};
It has basically required me to add the new key called 'message' within body and that has fixed the issue for me.