Introduction
Here is the full working code that shows up, how to send a push notification from .NET to your Android device(s) over new Google's Firebase Cloud (FCM) Service. All that works at 19.12.2017.
Background
My first attempt to do such relatively simple task was a real nightmare. After registration of project on Google Firebase Console, you get a whole bunch of IDs. Searching over the internet shows "How to do that and this and somewhat", but all of them fail, just because Google changes their API and name convention very quickly - I spend really a lot of time with PHP/Perl/C# code in order to sort out, what currently works. :)
Using the Code
First Check If Notification Works
- Go to Google Firebase Console on: https://console.firebase.google.com
- Login with your Google credentials
- Check Push Notification. Also see next topic for explanation about DeviceId.
Now Write Up Three Parameters of Your Application
serverKey
. That is a very long string
(151 chars in my case) got from URL like https://console.firebase.google.com/project/<your project name>/settings/cloudmessaging/android:<android package name>. You can reach this from "Project Overview"->"Project Settings"->Tab "Cloud Messaging". If you don't have one, simply click on "Add Server Key". You can also have multiply keys - I don't know what the reason is, but it works (for me) with any keys. I don't also know if it works with (short) "old server key". senderId
. You can find this just below server keys. It is very short, and has (currently) only 12 digits deviceId
. That is your (also very long) app-registration id on particular device. I don't want to explain this in detail how to get this one. This one is the same as InstanceId
of Registration Token associated to your App on your Device by Google Play Store Services. For explanation, see in the middle of text of this article. You don't need this one at all, if you want to notify all devices (use "/topics/all" or /topics/android etc.) or listen to particular notification and want to send particular notification (like "/topics/updateAvailable" etc.).
Now Create a WinForms C# Application
- Create a new C# WinForms application. For such a simply thing, I don't want mess with WPF. ;)
- Add assembly
System.Web.Extension
s to your assembly references collection. - Add Button with name
btnSendNotification
and Text "Send Notification" and empty TextBox
with name tbxResponse
. Align both on UI how you want. - Double-click on button
btnSendNotification
- it will generate an empty entry for Click-event. - Open file Form1.cs and put the following code:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
using System.Windows.Forms;
namespace WindowsFormsAppNotification
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnSendNotification_Click(object sender, EventArgs e)
{
tbxResponse.Clear();
string response = SendPushNotification();
tbxResponse.Text = response;
}
private static string SendPushNotification()
{
string response;
try
{
string serverKey = "AAAA0... ...._43";
string senderId = "908464655627";
string deviceId = "dj9...c:APA... .....WTw";
WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
to = deviceId,
notification = new
{
body = "Greetings",
title = "Augsburg",
sound = "Enabled"
}
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", serverKey));
tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
response = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
response = ex.Message;
}
return response;
}
}
}
Finally
- Set up your parameters
serverKey
, senderId
and deviceId
in code (see above) - Press Send Notification
- You should see a Response in your
TextBox
like this one:
{"multicast_id":7245675637858457127,"success":1,"failure":0,"canonical_ids":0,
"results":[{"message_id":"0:1513640171377700%6265d9e96265d9e9"}]}
- Now, if you use "/topics/all" notification, your response will be like only:
{"message_id":6032969957214653029}
- Again, in order to see specific topic notification messages, your App must be registered to it. More, it must handle such notification different from Background/Foreground state and must create screen-notification by itself as response to notification.
Last Words
Android and Google Service now follows the long wanted user guideline, that they don't restart app without user interaction if app is completely stopped. So, you will probably not see a notification after "Force Stop". On some devices / Android versions, the app will be "force stopped" by wipe out from screen.
Points of Interest
Did you learn anything ...
History
- 19.12.2017 - first (and for now last) version
-- Alex --