17

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?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Nikunj Ganatra
  • 171
  • 1
  • 1
  • 4

5 Answers5

9

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();
}
Guillermo Gutiérrez
  • 17,273
  • 17
  • 89
  • 116
  • I tried many diff code available across for sending GCM push.. and only this one works perfectly.. Other codes were working but I was getting push notification with blank message.. – hriziya Nov 08 '12 at 09:54
  • how to send multiple regid's to GCM? how to send text messages rather than "you got message". – Tej Dec 13 '12 at 11:38
  • 2
    What is GoogleAppID? Is it API key or packagename? – Jacek Apr 17 '13 at 07:50
  • Using the above code I am getting the server response like id=0:1374042920524416%5252b7a166d6cf16. Is I am doing anything wrong? i am using the applicationID as the API key from https://code.google.com/apis/console/ and senderID is the project number created using the above link. Please help me. – Karthick Jul 17 '13 at 06:37
  • For anyone: applicationID is the Google API key, the senderId is the google project id and the regId is the Id received from your phone when your phone registered at GCM. I can confirm it works, but a solution with json would be better, including multiple registrationId's. For references: https://developers.google.com/cloud-messaging/http – CularBytes Jul 01 '15 at 17:11
7

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();
3

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.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Zishan Neno
  • 2,647
  • 7
  • 34
  • 58
  • Hi Zishan, Thanks for the reply. You have posted code which has been implemented by using C2DM service. – Nikunj Ganatra Jun 29 '12 at 13:09
  • Hi, is there any sample or gudie line available for implementing Google Cloud Messaging (GCM) by using Asp.Net application? – Nikunj Ganatra Jul 02 '12 at 08:42
  • hi is there any solution available in Asp.net same as: http://developer.android.com/guide/google/gcm/demo.html – Nikunj Ganatra Jul 02 '12 at 08:42
  • Hi Nikunj, try the code that I posted above. It should work with GCM now. – Zishan Neno Jul 02 '12 at 10:54
  • Zishan, I have also implemented the code as per your direction. But I am getting error as : The remote server returned an error: (401) Unauthorized. At the following line: WebResponse Response = Request.GetResponse(); It may be because of the request url : "https://android.googleapis.com/gcm/send" *HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send"); Please check my last answer/reply for detail, as I have limited text so I could not give more details here. – Nikunj Ganatra Jul 05 '12 at 14:46
  • I think you might have not changed the API key that's being passed to the SendNotification function. I've tested the above code (against GCM) and it seems to be working for me. I'll post a complete tutorial on this in a few days. Until then, ping me on twitter (in my profile) and I can email you my project files etc. – Zishan Neno Jul 05 '12 at 23:03
  • Thanks again Zishan, 1. May I have any sample API, so I can get to know about charter length and format for that API. 2. can you please provide me any link, suggestion how I can get that exact API? 3. Sorry I could not found your email address, can you please provide me. Or can you please send any tutorial on nikunj.ganatra@clariontechnologies.com. Again Thank you very much for your great help – Nikunj Ganatra Jul 09 '12 at 06:57
  • Zishan, I have already obtain the API Key as per the : http://developer.android.com/guide/google/gcm/gs.html May I have one more clarification regarding Web Request URL: HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send"); is the above WebRequest URL is right? or it's just sample webrequest URL? – Nikunj Ganatra Jul 09 '12 at 07:10
  • Hi Nikunj, the URL in the above code is the exact URL to use. Pls check ur email, I've sent u my Android project and webform files that work the same as the code posted above. Cheers! – Zishan Neno Jul 09 '12 at 10:47
2

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.

CularBytes
  • 9,924
  • 8
  • 76
  • 101
0

Nikunj Ganatra, you can once check out this link for your error type, maybe your application id would be wrong or other details may be incorrect.. http://developer.android.com/guide/google/gcm/gcm.html#top

Response/Description

200 Message was processed successfully. The response body will contain more details about the message status, but its format will depend whether the request was JSON or plain text. See Interpreting a success response for more details.

400 Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected). The exact failure reason is described in the response and the problem should be addressed before the request can be retried.

401 There was an error authenticating the sender account.

500 There was an internal error in the GCM server while trying to process the request.

503 Indicates that the server is temporarily unavailable (i.e., because of timeouts, etc ). Sender must retry later, honoring any Retry-After header included in the response. Application servers must implement exponential back-off. The GCM server took too long to process the request.

I have just rectified it.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303