使用Asp.Net实现FCM(Firebase Cloud Messaging)推送通知

25

FCM

我已经使用以下方法通过asp .netGCM消息推送到Google服务器:

使用Asp.Net进行GCM推送通知

现在我计划升级到FCM方法,有没有人知道如何在asp .net中开发或实现此操作,请告知。


我使用了.NET管理SDK来完成这个任务。答案在这里 - Alfred Waligo
8个回答

66

2019年更新

现在有一个新的.NET管理SDK,允许您从服务器发送通知。使用Nuget进行安装

Install-Package FirebaseAdmin

你需要按照这里的说明下载服务账号密钥,并在你的项目中引用它。我可以通过像这样初始化客户端来发送消息。

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);
    }
    //...          
}

初始化应用程序后,您现在可以创建通知和数据消息并将它们发送到您想要的设备。

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
}

在您的服务集合中,然后您可以将其添加...

services.AddSingleton<IMobileMessagingClient, MobileMessagingClient >();

1
哇,我无法告诉你我等了多久才有一份来自Google的官方库。迫不及待想要尝试一下!感谢您发布这个,否则我就不会知道了! - Aaron Jordan
1
+1 为该SDK。应该是被接受的答案。在找到这篇文章后,我成功地运行了我的代码,并在10分钟内发送了成功的消息。谢谢! - J.B.
1
IMobileMessagingClient这个库是从哪里来的?它似乎不在Firebase库或我能找到的任何其他库中。 - After_Sunset
我遇到了问题:FirebaseApp.Create(new AppOptions() { Credential = GoogleCredential.FromFile("serviceAccountKey.json").CreateScoped("https://www.googleapis.com/auth/firebase.messaging")});我认为这是由于CreatedScope链接出现404错误导致的。我使用了文档中提供的IHostingEnvironment和GoogleCredentials来创建消息变量:var credential = GoogleCredential.FromFile(jsonPath); var app = FirebaseApp.Create(new AppOptions() { Credential = credential }); var messaging = FirebaseMessaging.GetMessaging(app); - armourshield
答案很好,应该标记为已接受。但是,我有一个问题,为什么要使用services.AddSingleton而不是AddScopedAddTransient - Grigory Zhadko
显示剩余6条评论

29

C# 服务器端代码 用于 Firebase 云消息传递

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和senderId的获取方式,具体步骤如下(参见下图):

步骤 1

步骤 2

步骤 3


3
设备 ID 从哪里获取? - Darshan Miskin
这是在服务中使用FirebaseInstanceId.getInstance().getToken()方法生成的令牌。 - Nilesh
已经弄清楚了,服务是FirebaseInstanceIdService。此外,即使按照这里所说的做法->https://dev59.com/Gmkv5IYBdhLWcg3w_lzE,tRequest.GetResponse()仍会抛出“远程服务器返回错误:(401)未经授权。”错误。还有其他解决方案吗? - Darshan Miskin
我正在使用你的代码。忽略应用程序方面,它正常工作,我已经使用 Firebase 控制台进行了测试。我所说的错误发生在 C# 代码中。 - Darshan Miskin
5
不是使用Web应用程序的API密钥,而是使用在项目设置>云消息中找到的服务器密钥(而不是旧版服务器密钥)。这样就可以让它正常工作了。 - Darshan Miskin
显示剩余6条评论

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;
    }
}

这对于未使用WCF的ASP.net C#非常有用。 - BALU K B
1
嗨,你从哪里获取设备令牌? - men

4
为了访问Firebase API,我们需要一些Firebase的信息,包括API URL (https://fcm.googleapis.com/fcm/send) 和唯一的密钥来识别我们的Firebase项目以确保安全。
我们可以使用以下方法从.NET Core后端发送通知:
        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);
        }
    }

以下是这些参数:

  • token: 字符串,代表Firebase在每次应用安装时提供的FCM令牌。这将是通知要发送的应用程序安装列表。
  • title: 它是通知的粗体部分。
  • body: 它表示Firebase SDK的“消息文本”字段,这是您想要发送给用户的消息。

要查找您的Sender ID和API密钥,您需要执行以下操作:

  • 登录Firebase Developer Console并转到您的控制台
  • 单击“齿轮”图标并访问“项目设置”
  • 进入“Cloud Messaging Section”,您将可以访问发件人ID和API密钥。 enter image description here

2

以下是我的VBScript示例,适用于偏爱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

2

使用CorePush库

这个库非常轻量级。我在所有项目中都使用它来发送Firebase的AndroidWebPush和苹果iOS推送通知。有用的链接:

  1. NuGet包
  2. 文档

接口非常简单和极简:

发送APN消息

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

发送 FCM 消息:

var fcm = new FcmSender(settings, httpClient);
await fcm.SendAsync(deviceToken, notification);

它在本地机器上运行良好,但当我上传到远程服务器时,我收到了500内部服务器错误状态代码。请问您对这个错误有什么想法吗? - Dark Knight
@DarkKnight 确保你的凭据和一切都是正确的。另外,SSL证书可能会有一些问题。你有更详细的错误信息吗?你是将推送发送到苹果还是 FCM? - Andrei
不,我只在Android设备上测试过,而且我没有任何关于它的详细信息,因为在我的远程服务器上,我只能得到500状态码的内部服务器错误。 - Dark Knight

2

2020/11/28

从 Firebase -> 设置 -> 服务帐户 -> Firebase Admin SDK 下载此文件。

enter image description here

将下载的文件移动到您的 dotnet Core 根目录,然后将其名称更改为 key.json。

然后在您的项目根目录中的YourProjectName.csproj文件中添加以下代码:

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

然后将以下代码添加到您的 Program.cs 文件中的 Main 函数:

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

最后一件事是推送通知的代码:
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);
}

将其放置在任何控制器中,您就可以调用它来发送通知...
这就是我用来推送通知的方法,它非常有效和快速...

在 Program.cs 中导入: using FirebaseAdmin.Messaging;用于推送通知的导入: using FirebaseAdmin; using Google.Apis.Auth.OAuth2; - Mehmed Cuhadar

0

我不相信你发送推送通知的方式有任何变化。在 FCM 中,你将以与 GCM 相同的方式进行 HTTP POST 请求:

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..."
}

阅读有关FCM服务器的更多信息。

现在我能看到的唯一变化是目标URL。句号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接