C#Firebase Cloud消息使用主题消息发送多个Web JS通知



我正在尝试使用主题发送多个Web通知,而不是向每个令牌发送通知。

,但我坚持使用 401 unauthorized

凭证将通知发送到主题

这是我的代码

首先,我请求Web浏览器权限通过此Firebase示例代码通知令牌:https://github.com/firebase/quickstart-js/blob/master/master/messaging

index.html上,i更改这样的代码以将令牌发送到服务器以订阅主题

    function resetUI() {
        clearMessages();
        // [START get_token]
        // Get Instance ID token. Initially this makes a network call, once retrieved
        // subsequent calls to getToken will return from cache.
        messaging.getToken().then(function (currentToken) {
            if (currentToken) {
                console.log("Get Token OK: " + currentToken);
                sendTokenToServer(currentToken);
            } else {
                // Show permission request.
                console.log('No Instance ID token available. Request permission to generate one.');
                // Reset Token on Server to False
                setTokenSentToServer(false);
                // Request permission for Token
                requestPermission();
            }
        }).catch(function (err) {
            console.log('An error occurred while retrieving token. ', err);
            setTokenSentToServer(false);
        });
        // [END get_token]
    }

    // Send the Instance ID token your application server, so that it can:
    // - send messages back to this app
    // - subscribe/unsubscribe the token from topics
    function sendTokenToServer(currentToken) {
        if (!(window.localStorage.getItem('EDXNotificationIsSentToServer') === '1')) {
            console.log('Sending token to server...');
            var tokenObject = {
                token: currentToken
            };
            $.ajax({
                type: "POST",
                url: '@Url.Action("SaveToken", "Api")',
                data: JSON.stringify(tokenObject),
                contentType: "application/json; charset=utf-8",
                success: function (data) {
                    if (data) {
                        // TODO(developer): Send the current token to your server.
                        setTokenSentToServer(true);
                    }
                },
                complete: function (status) {
                },
                error: function (error) { }
            });
        } else {
            console.log('Token already sent to server so won't send it again unless it changes');
        }
    }

在服务器上,我将令牌存储到数据库中并订阅以测试主题

    public class ApiController : Controller
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        /// <summary>
        /// Lưu token
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public JsonResult SaveToken(TBL_Customer_Tokens model)
        {
            try
            {
                if (!string.IsNullOrEmpty(model.token))
                {
                    bool ret = true;
                    if(GCMUtils.SubcribeTokenToTopic(model.token, ConfigurationManager.AppSettings["GCMTopic"]))
                        ret = DataServiceFactory.GetCustomerService().SaveToken(model.token); // Save token to database, don't care about this function. It is ok
                    if (ret)
                        Json(true, JsonRequestBehavior.AllowGet);
                }
            }
            catch (Exception ex)
            {
                log.Debug(ex.Message, ex);
            }
            return Json(false, JsonRequestBehavior.AllowGet);
        }
    }

这是gcmutils

    public class GCMUtils
    {
        private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public static bool SubcribeTokenToTopic(string token, string topic)
        {
            try
            {
                string url = String.Format("https://iid.googleapis.com/iid/v1/{0}/rel/topics/{1}", token, topic);
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                req.ContentType = "application/json";
                req.Headers.Add("Authorization", "key=" + ConfigurationManager.AppSettings["GCMServerKey"]);

                req.Method = "POST";
                req.ContentLength = 0;
                Stream reqStream = req.GetRequestStream();
                reqStream.Close();
                HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                    return true;
            }
            catch (Exception ex)
            {
                log.Debug(ex.Message, ex);
            }
            return false;
        }
    }
检索

令牌,保存到数据库并成功订阅了主题。因此,您可以忽略上面的代码,仅分析问题belows

其次,我正在尝试将网络通知发送到主题,而不是向每个令牌发送单个通知

    public static bool SendFirebaseTopicNotificationAsync(string topicSubscription, NotificationPayload dat)
    {
        try
        {
            List<string> scopes = new List<string>();
            scopes.Add("https://www.googleapis.com/auth/firebase");
            scopes.Add("https://www.googleapis.com/auth/firebase.messaging");
            string accesstoken = GoogleCredential.FromFile(ConfigurationManager.AppSettings["GoogleCredentialFilePath"])
                                                        .CreateScoped(scopes)
                                                        .UnderlyingCredential
                                                        .GetAccessTokenForRequestAsync().Result;
            WebRequest tRequest = WebRequest.Create("https://fcm.googleapis.com/v1/projects/test-project/messages:send");
            tRequest.Method = "post";

            tRequest.Headers.Add("Authorization", "bearer " + accesstoken);
            tRequest.ContentType = "application/json";
            var payload = new
            {
                message = new
                {
                    topic = topicSubscription,
                    notification = new {
                        title = dat.title,
                        body = dat.body
                    },
                    webpush = new
                    {
                        fcm_options = new {
                            link = dat.click_action
                        }
                    }
                }
            };
            string postbody = JsonConvert.SerializeObject(payload).ToString();
            Byte[] byteArray = Encoding.UTF8.GetBytes(postbody);
            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())
                    {
                        if (dataStreamResponse != null) using (StreamReader tReader = new StreamReader(dataStreamResponse))
                            {
                                String sResponseFromServer = tReader.ReadToEnd();
                                Console.WriteLine(sResponseFromServer);
                                return true;
                            }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            log.Debug(ex.Message, ex);
        }
        return false;
    }

请注意,SendFirebaseTopicNotificationAsync中的test-project是项目名称。我确定这是真的

ConfigurationManager.AppSettings["GoogleCredentialFilePath"]是通往.json密钥文件的绝对文件路径form-json-or-p12-key-in-c-sharp/

,但我得到401 Unauthorized错误。GoogleCredential的访问令牌似乎是错误的

任何帮助将不胜感激

谢谢

愚蠢的错误这是这行

    tRequest.Headers.Add("Authorization", "bearer " + accesstoken);

bearer是错误的,使用 Bearer而不是

    tRequest.Headers.Add("Authorization", "Bearer " + accesstoken);

我还找到了这篇文章https://github.com/googleapis/google-api-dotnet-client/issues/1140

这个家伙也有401 Unauthorized。但是他的问题与我不同。他在Google Cloud Platform https://console.cloud.google.com/apis/dashboard

相关内容

  • 没有找到相关文章

最新更新