25

FCM

I have already push the GCM message to google server using asp .net in following method,

GCM Push Notification with Asp.Net

Now i have planned upgrade to FCM method, anyone have idea about this or developing this in asp .net let me know..

Community
  • 1
  • 1
bgs
  • 3,061
  • 7
  • 40
  • 58

8 Answers8

64

2019 Update

There's a new .NET Admin SDK that allows you to send notifications from your server. Install via Nuget

Install-Package FirebaseAdmin

You'll then have to obtain the service account key by downloading it by following the instructions given here, and then reference it in your project. I've been able to send messages by initializing the client like this

using FirebaseAdmin;
using FirebaseAdmin.Messaging;
using Google.Apis.Auth.OAuth2;
...

public class MobileMessagingClient : IMobileMessagingClient
{
    private readonly FirebaseMessaging messaging;

    public MobileMessagingClient()
    {
        var app = FirebaseApp.Create(new AppOptions() { Credential = GoogleCredential.FromFile("serviceAccountKey.json").CreateScoped("https://www.googleapis.com/auth/firebase.messaging")});           
        messaging = FirebaseMessaging.GetMessaging(app);
    }
    //...          
}

After initializing the app you are now able to create notifications and data messages and send them to the devices you'd like.

private Message CreateNotification(string title, string notificationBody, string token)
{    
    return new Message()
    {
        Token = token,
        Notification = new Notification()
        {
            Body = notificationBody,
            Title = title
        }
    };
}

public async Task SendNotification(string token, string title, string body)
{
    var result = await messaging.SendAsync(CreateNotification(title, body, token)); 
    //do something with result
}

..... in your service collection you can then add it...

services.AddSingleton<IMobileMessagingClient, MobileMessagingClient >();
Alfred Waligo
  • 2,809
  • 3
  • 18
  • 26
  • 1
    Wow I can't tell you how long I've been waiting for an official lib from Google. Can't wait to try this out! Thanks for posting this, I never would've known! – Aaron Jordan May 08 '19 at 20:28
  • 1
    +1 for the SDK. Should be accepted answer. Had my code up and running, sending successful messages within 10 minutes of finding this post. Thanks! – J.B. Aug 15 '19 at 13:05
  • 1
    What library is IMobileMessagingClient coming from? It doesn't seem to be in the Firebase library or any other that I can locate. – After_Sunset Sep 15 '19 at 17:19
  • that's just an interface of my own that I decided to create, its not necessary, you could just write your own or not use one at all – Alfred Waligo Sep 15 '19 at 21:10
  • I had problems with ``` FirebaseApp.Create(new AppOptions() { Credential = GoogleCredential.FromFile("serviceAccountKey.json").CreateScoped("https://www.googleapis.com/auth/firebase.messaging")}); ``` I think it is due the CreatedScope link which was getting 404 error. I used IHostingEnvironment and GoogleCredentials which is in the documentation to create messaging variable ``` var credential = GoogleCredential.FromFile(jsonPath); var app = FirebaseApp.Create(new AppOptions() { Credential = credential }); var messaging = FirebaseMessaging.GetMessaging(app); ``` – armourshield Jan 03 '20 at 12:28
  • I gave up using on that. Everytime i had the error saying the key was invalid. When i was using another method (wiithout the json file), it was working. – paboobhzx Feb 13 '20 at 17:55
  • Worked like a charm! Thanks! Have an issue to get the value of the token. Receive one from client app which is working fine when passed to notification sending API. But as the user is unsubscribed from receiving notifications, the token is changed. Tried this but can't receive notifications: using (var stream = new FileStream("accountKey.json", FileMode.Open, FileAccess.Read)){var credential = GoogleCredential.FromStream(stream).CreateScoped("https://www.googleapis.com/auth/firebase.messaging");return await credential.UnderlyingCredential.GetAccessTokenForRequestAsync().ConfigureAwait(false); – Karishma Mar 06 '20 at 11:25
  • Can anyone expand on the SDK code to include the sending of an image? I've got successful notifications firing, but populating the ImageUrl on the Notification object just does not work - and yes, my image is available publicly. I was hoping for a better solution to using a generic WebRequest for notifications, but this SDK doesn't appear to add anything useful. What advantage is there in "upgrading" to it? – Flippsie May 07 '20 at 09:20
  • How can i get token to pass to SendNotifications – Ratheesh Feb 20 '21 at 13:07
  • The answer is great and should be marked as Accepted. However, I have a question, why do you use `services.AddSingleton` instead of `AddScoped` or `AddTransient`? – Grigory Zhadko May 27 '21 at 11:59
  • Yeah needs updated to show how to get the token please edit ur answer – c-sharp-and-swiftui-devni Sep 25 '21 at 06:00
29

C# Server Side Code For Firebase Cloud Messaging

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Script.Serialization;

namespace Sch_WCFApplication
{
    public class PushNotification
    {
        public PushNotification(Plobj obj)
        {
            try
            {    
                var applicationID = "AIza---------4GcVJj4dI";

                var senderId = "57-------55";

                string deviceId = "euxqdp------ioIdL87abVL";

                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 = obj.Message,

                        title = obj.TagMsg,

                        icon = "myicon"

                    }    
                };       

                var serializer = new JavaScriptSerializer();

                var json = serializer.Serialize(data);

                Byte[] byteArray = Encoding.UTF8.GetBytes(json);

                tRequest.Headers.Add(string.Format("Authorization: key={0}", applicationID));

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

                                string str = sResponseFromServer;

                            }    
                        }    
                    }    
                }    
            }        

            catch (Exception ex)
            {

                string str = ex.Message;

            }          

        }   

    }
}

APIKey and senderId , You get is here---------as follow(Below Images) (go to your firebase App)

Step. 1

Step. 2

Step. 3

Darshan Miskin
  • 844
  • 14
  • 25
Nilesh
  • 1,013
  • 14
  • 21
  • 3
    where to get the device id from? – Darshan Miskin Dec 02 '16 at 10:59
  • It is a token generated using a method FirebaseInstanceId.getInstance().getToken() in a Service – Nilesh Dec 02 '16 at 12:14
  • Figured that out.. the service is FirebaseInstanceIdService. Also, tRequest.GetResponse() throws a "The remote server returned an error: (401) Unauthorized." Error, even after doing whats said here-> http://stackoverflow.com/questions/10205854/error-the-remote-server-returned-an-error-401-unauthorized Any other solutions? – Darshan Miskin Dec 02 '16 at 12:45
  • Please use the code (Above i posted) instead of you used.... i hope you get the error free through..... – Nilesh Dec 02 '16 at 13:01
  • i am using your code.. ignore the app side, it is working properly have tested it using firebase console.. the error which i am talking about happens in the c# code – Darshan Miskin Dec 02 '16 at 13:03
  • No not at all, it is a tested code,and have used in a live android app. Please try again may be you have done some silly things – Nilesh Dec 02 '16 at 13:06
  • Actually, I have the Same Problem which is only due to wrong Application Id – Nilesh Dec 02 '16 at 13:08
  • application id, sender id and token are all correct. Still the same error. "The remote server returned an error: (401) Unauthorized." – Darshan Miskin Dec 02 '16 at 13:20
  • have u tested the message from firebase console? – Nilesh Dec 02 '16 at 13:22
  • yup, got the notification for the targeted single device. – Darshan Miskin Dec 02 '16 at 13:27
  • 5
    instead of using the api key from web app, had to use the server key(not the legacy server key) found in project settings>cloud messaging. This got it working. – Darshan Miskin Dec 09 '16 at 07:42
13
 public class Notification
{
    private string serverKey = "kkkkk";
    private string senderId = "iiddddd";
    private string webAddr = "https://fcm.googleapis.com/fcm/send";

    public string SendNotification(string DeviceToken, string title ,string msg )
    {
        var result = "-1";
        var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
        httpWebRequest.ContentType = "application/json";
        httpWebRequest.Headers.Add(string.Format("Authorization: key={0}", serverKey));
        httpWebRequest.Headers.Add(string.Format("Sender: id={0}", senderId));
        httpWebRequest.Method = "POST";

        var payload = new
        {
            to = DeviceToken,
            priority = "high",
            content_available = true,
            notification = new
            {
                body = msg,
                title = title
            },
        };
        var serializer = new JavaScriptSerializer();
        using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
        {
            string json = serializer.Serialize(payload);
            streamWriter.Write(json);
            streamWriter.Flush();
        }

        var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            result = streamReader.ReadToEnd();
        }
        return result;
    }
}
EraMaX
  • 186
  • 1
  • 5
4

To hit Firebase API we need some information from Firebase, we need the API URL (https://fcm.googleapis.com/fcm/send) and unique keys that identify our Firebase project for security reasons.

We can use this method to send notifications from .NET Core backend:

        public async Task<bool> SendNotificationAsync(string token, string title, string body)
    {
        using (var client = new HttpClient())
        {
            var firebaseOptionsServerId = _firebaseOptions.ServerApiKey;
            var firebaseOptionsSenderId = _firebaseOptions.SenderId;

            client.BaseAddress = new Uri("https://fcm.googleapis.com");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization",
                $"key={firebaseOptionsServerId}");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Sender", $"id={firebaseOptionsSenderId}");


            var data = new
            {
                to = token,
                notification = new
                {
                    body = body,
                    title = title,
                },
                priority = "high"
            };

            var json = JsonConvert.SerializeObject(data);
            var httpContent = new StringContent(json, Encoding.UTF8, "application/json");

            var result = await _client.PostAsync("/fcm/send", httpContent);
            return result.StatusCode.Equals(HttpStatusCode.OK);
        }
    }

These parameters are:

  • token: string represents a FCM token provided by Firebase on each app-installation. This is going to be the list of app-installations that the notification is going to send.
  • title: It’s the bold section of notification.
  • body: It represents “Message text” field of the Firebase SDK, this is the message you want to send to the users.

To find your Sender ID and API key you have to:

  • Login to the Firebase Developer Console and go to your Dashboard
  • Click on the “gear” icon and access “project settings”
  • Go to the “Cloud Messaging Section” and you will have access to the sender ID and the API Key. enter image description here
Anastasia
  • 452
  • 5
  • 7
2

Here is my VbScript sample for who prefers vb:

//Create Json body
posturl="https://fcm.googleapis.com/fcm/send"
body=body & "{ ""notification"": {"
body=body & """title"": ""Your Title"","
body=body & """text"": ""Your Text"","
body=body & "},"
body=body & """to"" : ""target Token""}"

//Set Headers :Content Type and server key
set xmlhttp = server.Createobject("MSXML2.ServerXMLHTTP")
xmlhttp.Open "POST",posturl,false
xmlhttp.setRequestHeader "Content-Type", "application/json"
xmlhttp.setRequestHeader "Authorization", "Your Server key"

xmlhttp.send body
result= xmlhttp.responseText
//response.write result to check Firebase response
Set xmlhttp = nothing
Ali Sheikhpour
  • 10,475
  • 5
  • 41
  • 82
2

2020/11/28

download this file from Firebase -> Settings -> Service accounts -> Firebase Admin SDK

enter image description here

Move the downloaded file to Your dotnet Core Root folder then change it's name to key.json for example .

then add this code to your .csproj file: YourProjectName.csproj in your project root folder :

  <ItemGroup>
    <None Update="key.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

then add this code to your Program.cs in Main function :

var defaultApp = FirebaseApp.Create(new AppOptions()
{
  Credential = 
  GoogleCredential.FromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, 
  "key.json")),
});

Last thing is the code that will push notification :

public async Task SendNotificationAsync(string DeviceToken, string title ,string body){
 var message = new Message()
 {
  Notification = new FirebaseAdmin.Messaging.Notification
  {
     Title = title,
     Body = body
  },
  Token = DeviceToken,
 };
 var messaging = FirebaseMessaging.DefaultInstance;
 var result = await messaging.SendAsync(message);
}

Put it in any Controller then u can call it to send notification ...

that is what i did to push notificaion and it is working very well and fast ...

Mehmed Cuhadar
  • 121
  • 1
  • 4
  • in Program.cs import : using FirebaseAdmin.Messaging; for pushnotification import : using FirebaseAdmin; using Google.Apis.Auth.OAuth2; – Mehmed Cuhadar Nov 28 '20 at 15:01
2

Use CorePush lib

It's very lightweight. I use it across all my projects to send Firebase Android, WebPush and Apple iOS push notifications. Useful links:

  1. NuGet package
  2. Documentation

The interface is very simple and minimalistic:

Send APN message:

var apn = new ApnSender(settings, httpClient);
await apn.SendAsync(notification, deviceToken);

Send FCM message:

var fcm = new FcmSender(settings, httpClient);
await fcm.SendAsync(deviceToken, notification);
Andrei
  • 42,814
  • 35
  • 154
  • 218
  • It's working on the local machine but when i upload to the remote server , i got the internal server error status code 500 . please do you have any idea for this error? – Dark Knight Jul 02 '22 at 14:07
  • @DarkKnight Make sure your credentials and everything is correct. Also, there may be some issues with SSL certificates. Do you have a more detailed error? Where are you sending your push? Is it Apple or FCM? – Andrei Jul 02 '22 at 16:19
  • no i have testing it on the android device only , and i have no any details about it because on my remote server on i can got the 500 status code internal server error – Dark Knight Jul 02 '22 at 17:52
0

I don't believe there is any change in the way you are sending push notifications. In FCM also, you are going to make HTTP POST Request the same way you did for GCM:

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}

Read about FCM Server for more information.

The only change I could see now, is the target Url. Period.

Chintan Soni
  • 24,761
  • 25
  • 106
  • 174