Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCM Push Notification with Asp.Net

As you may have seen, Google is migrating its Push Notification System.

http://developer.android.com/guide/google/gcm/c2dm.html

Is there any sample or guide line available for implementing Google Cloud Messaging (GCM) by using an Asp.Net application?

like image 305
Nikunj Ganatra Avatar asked Jun 29 '12 12:06

Nikunj Ganatra


4 Answers

I have a piece of code which is working fine for me and could be helpful, I tested it out...

void send(string regId)
{
    var applicationID = "xxxxxxxx";


    var SENDER_ID = "xxxxx";
    var value = txtMsg.Text;
    WebRequest tRequest;
    tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
    tRequest.Method = "post";
    tRequest.ContentType = " application/x-www-form-urlencoded;charset=UTF-8";
    tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));

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

    // string postData = "{ 'registration_id': [ '" + regId + "' ], 'data': {'message': '" + txtMsg.Text + "'}}";
    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=" + regId + "";
    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();

    lblStat.Text = sResponseFromServer;
    tReader.Close();
    dataStream.Close();
    tResponse.Close();
}
like image 140
user1551788 Avatar answered Nov 08 '22 00:11

user1551788


here is the code in c#

 WebRequest tRequest;
        tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
        tRequest.Method = "post";
        tRequest.ContentType = "application/x-www-form-urlencoded";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", GoogleAppID));
String collaspeKey = Guid.NewGuid().ToString("n");
String postData=string.Format("registration_id={0}&data.payload={1}&collapse_key={2}", DeviceID, "Pickup Message" + DateTime.Now.ToString(), collaspeKey);
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();
like image 42
Steve The Sultan Avatar answered Nov 07 '22 23:11

Steve The Sultan


A while back I had been playing around with C2DM to send push notifications. I altered my code as per changes mentioned on this page: http://developer.android.com/guide/google/gcm/c2dm.html#server to make use for GCM service:

Private Sub btnPush_Click(sender As Object, e As System.EventArgs) Handles btnPush.Click
    lblResponse.Text = SendNotification(AIzaSyB-1uEai2WiUapxCs2Q0GZYzPu7Udno5aA)
End Sub

My SendNotification function:

Private Function SendNotification(ByVal authstring As String) As String
    ServicePointManager.ServerCertificateValidationCallback = Function(sender As Object, certificate As X509Certificate, chain As X509Chain, sslPolicyErrors As SslPolicyErrors) True
    Dim request As WebRequest = WebRequest.Create("https://android.googleapis.com/gcm/send")
    request.Method = "POST"
    request.ContentType = "application/x-www-form-urlencoded"
    request.Headers.Add(String.Format("Authorization: key={0}", authstring))
    Dim collaspeKey As String = Guid.NewGuid().ToString("n")
    Dim postData As String = String.Format("registration_id={0}&data.payload={1}&collapse_key={2}", deviceList.SelectedValue, txtPayload.Text, collaspeKey)
    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
    request.ContentLength = byteArray.Length
    Dim dataStream As Stream = request.GetRequestStream()
    dataStream.Write(byteArray, 0, byteArray.Length)
    dataStream.Close()
    Dim response As WebResponse = request.GetResponse()
    dataStream = response.GetResponseStream()
    Dim reader As New StreamReader(dataStream)
    Dim responseFromServer As String = reader.ReadToEnd()
    reader.Close()
    dataStream.Close()
    response.Close()

    Return responseFromServer
End Function

It seems that GCM does not require you to authenticate against Google to obtain an auth key (as the case was with C2DM). Instead, you'll require an API key which is being passed to the SendNotification function. This page should help you get your API key set up: http://developer.android.com/guide/google/gcm/gs.html

The code for my web form is below just in case:

<form id="form1" runat="server">
<div>
    <asp:DropDownList ID="deviceList" runat="server">
        <asp:ListItem Value="device-id-goes-here">Eclipse AVD</asp:ListItem>
        <asp:ListItem Value="device-id-goes-here">My Phone 1</asp:ListItem>
        <asp:ListItem Value="device-id-goes-here">My Phone 2</asp:ListItem>
    </asp:DropDownList>
    <br /><br />
    <asp:TextBox ID="txtPayload" runat="server" Width="480px"></asp:TextBox>
    <br /><br />
    <asp:Button ID="btnPush" runat="server" Text="Push" />
    <asp:Label ID="lblResponse" runat="server" Text=""></asp:Label>
</div>
</form>

As for creating your Android app to receiving the push notifications, check out this link: http://developer.android.com/guide/google/gcm/gs.html#android-app

Don't forget to import System.Net, System.IO, System.Security.Cryptography.X509Certificates and System.Net.Security.

like image 3
Zishan Neno Avatar answered Nov 07 '22 23:11

Zishan Neno


JSON way

user1551788 answer works fine, however I like to do it in JSON, which is better practice instead of inserting everything in one line, I think.

The internal class 'jsonObj' is the same as the documentation requires, check the different requests you can make here

A brief description:

to: the phone to send to, insert the registrationId that you received from the phone here. delay_while_idle By using the delay_while_idle flag, notifications will be delivered once the device becomes active. (out of lock, when the user really uses the phone).

data: set data with custom key/value pairs to pass additional payload to the client app. So, you can put in any variable you want, if you like a json string that contains another object, as long as it does not exceed 4 KB.

Some that are also available that I didn't use.

collapse_key: If set, a notification that has the same collapse_key name should be overwrite the older notification (metter of good implementation at the phone side when notification is send, on the GCM server it will overwrite when the notification is pending).

time_to_live: Straight forward, how long the notification will stay alive, currently not supported for IOS.

Some other, see documentation.

internal class because I didn't need that object outside of my class, which is better for naming like 'data' that could be anything.

private void SendPostsToGCM(jsonObj jsonObj)
    {            
        string senderId = "your project number (google)";
        string apiKey = "your apiKey, found on console";

        WebRequest tRequest;
        tRequest = WebRequest.Create("https://android.googleapis.com/gcm/send");
        tRequest.Method = "post";

        tRequest.ContentType = "application/json";
        tRequest.Headers.Add(string.Format("Authorization: key={0}", apiKey));
        tRequest.Headers.Add(string.Format("Sender: id={0}", senderId));

        string jsonPostData = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj); //download Newtonsoft NuGet package

        Byte[] byteArray = Encoding.UTF8.GetBytes(jsonPostData);
        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();

        string response = sResponseFromServer;
        tReader.Close();
        dataStream.Close();
        tResponse.Close();
    }

    internal class jsonObj
    {
        public bool delay_while_idle { get; set; }
        public data data { get; set; }
        public string to { get; set; }
    }

    internal class data
    {
        public int Id { get; set; }
        public string text { get; set; }
    }

To use, simply:

    //some filtering to select some posts or whatever.
    jsonObj jsonPostData = new jsonObj()
    {
        delay_while_idle = true,
        to = registrationGCMid,
        data = new data()
        {
            Id = post.id,
            text = post.text,
        }
    };
SendPostsToGCM(jsonPostData);

Another great difference I have noticed, the google service returns a json string containing useful information, it tells how many succeeded and how many failed, etc.

like image 2
CularBytes Avatar answered Nov 08 '22 00:11

CularBytes