0

I am trying to use FCM API for sending push notifications on a android application. It works nice if I use some HTTP client like Insomnia or Postman. Is the screen below:

enter image description here

and headers:

enter image description here

Of course, I have a registration ID and FCM Server key instead of xxx.

But I need to send the same from my C# code. And I always have BadRequest. I don't understand why.

Here is my code:

var json = JsonConvert.SerializeObject(new
{
    to = customer.FcmRegistrationId,
    notification = new
    {
        body = push.PushBody,
        title = push.PushTitle,
        sound = "default"
    }
});

var content = new StringContent(json, Encoding.UTF8, "application/json");

var request = new HttpRequestMessage
{
    RequestUri = new Uri("https://fcm.googleapis.com/fcm/send"),
    Content = content,
};

request.Headers.TryAddWithoutValidation("Authorization", 
    "key=" + customer.FCMServerKey);

HttpResponseMessage response;

using (var client = new HttpClient())
{
    response = await client.SendAsync(request);
}

response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync(); 

And as I've sad before I always have this answer:

enter image description here

Please help me!

Community
  • 1
  • 1
Aleksej_Shherbak
  • 2,757
  • 5
  • 34
  • 71
  • Can you add a proxy like fiddler to check the both payloads? That's where I would start from. Add the proxy and check Headers,Body etc – Athanasios Kataras Oct 01 '19 at 13:29
  • Thank you. I will try. I never use it before. – Aleksej_Shherbak Oct 01 '19 at 13:32
  • Bad request is almost always a typo on one or multiple fields of your payload. Bear in mind that the serialization will result in one-to-one variable to sent field. So check your class member names to make sure it maps the postman payload. – Athanasios Kataras Oct 01 '19 at 13:33
  • I have checked all fields. I had made json dump and put it into `Insomnia` http client. And I have done the same for server auth key. And all works! – Aleksej_Shherbak Oct 01 '19 at 13:41
  • Then you need to check the exact payload that the Http client creates in order to figure this out (fiddler or some such). – Athanasios Kataras Oct 01 '19 at 13:43
  • I've installed fiddler and I will try just now. – Aleksej_Shherbak Oct 01 '19 at 13:44
  • Ok I have checked traffic with the help of fiddler. And I have nothing ( When my C# code make request to FCM I don't see request in the fiddler but when I make something like `curl http://ya.ru` in the terminal I can see the result in the fiddler. Maybe I use it wrong? – Aleksej_Shherbak Oct 01 '19 at 13:53
  • Have you tried this? https://stackoverflow.com/questions/22500299/how-can-i-trace-the-httpclient-request-using-fiddler-or-any-other-tool – Athanasios Kataras Oct 01 '19 at 13:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200243/discussion-between-aleksej-shherbak-and-athanasios-kataras). – Aleksej_Shherbak Oct 01 '19 at 14:06

2 Answers2

1

I have testet an approach to send push notifications: uses WebRequest.Create

Please set devId (reg-id from your at the fcm registerd device), SERVER_API_KEY und SENDER_ID from your fcm-account.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net;

namespace SendMsgByFCM
{
    public partial class Form1 : Form
    {

        AndroidGCMPushNotification fcmPush = new AndroidGCMPushNotification();


        public Form1()
        {
            InitForm();
            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {
             **devId** = "faxgYiWv4Sk:APA91bGehlGNNGaE20djfaJ5xzQst_b190GvrEwm_yvPsZvY-.....";
            fcmPush.SendNotification(devId, 'message ...' );
            MessageBox.Show( "msg send" );
        }
    }

    public class AndroidGCMPushNotification
    {

        public string SendNotification(string deviceId, string message)
        {
            string **SERVER_API_KEY** = "AAAADtSR7s8:APA91bHhhsjRMeL2gH6Qzv5BbdJyshOtgJ-J....";

            var **SENDER_ID** = "636988888888";
            var value = message;
            WebRequest tRequest;
            tRequest = **WebRequest.Create**("https://fcm.googleapis.com/fcm/send");
            tRequest.Method = "post";
            tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
            tRequest.Headers.Add(string.Format("Authorization: key={0}", SERVER_API_KEY));

            tRequest.Headers.Add(string.Format("Sender: id={0}", SENDER_ID));

            string postData = "collapse_key=score_update&time_to_live=108&delay_while_idle=1&data.message=" + value + "&data.time=" + System.DateTime.Now.ToString() + "&registration_id=" + deviceId + "";
            Console.WriteLine(postData);
            Byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            tRequest.ContentLength = byteArray.Length;

            Stream dataStream = tRequest.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            WebResponse tResponse = tRequest.GetResponse();

            dataStream = tResponse.GetResponseStream();

            StreamReader tReader = new StreamReader(dataStream);

            String sResponseFromServer = tReader.ReadToEnd();


            tReader.Close();
            dataStream.Close();
            tResponse.Close();
            return sResponseFromServer;
        }
    }
}
Micha
  • 906
  • 6
  • 9
0

I have solved it with the help of the following code:

using (var client = new HttpClient())
{

client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"key={ServerKey}");
var obj = new
{
    to = Id,
    notification = new
    {
        title = Title,
        body = Message

    }
};

//serialize object data to json
string json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
// create an http string content
var data = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("https://fcm.googleapis.com/fcm/send", data);
return response.StatusCode;

...

Full source is here https://github.com/frankodoom/Firebase.Notification/blob/master/Firebase.Network.Standard/Firebase.cs

I dont know why but data and text in the original source dont work. Use title and body.

Aleksej_Shherbak
  • 2,757
  • 5
  • 34
  • 71