在Ruby on Rails中使用Typhoeus :: Request向FCM发送请求

时间:2021-07-28 07:34:58

I would like to send a simple request to FCM using Typhoeus::Request. It seems I'm doing something terribly wrong but can't come up with any clues since a few hours...

我想使用Typhoeus :: Request向FCM发送一个简单的请求。看来我做的事情非常糟糕,但几个小时后就无法提出任何线索......

This is how I send request to FCM:

这是我向FCM发送请求的方式:

req = Typhoeus::Request.new(
        Fcm_server_uri,
        method: :post,
        params: {:to => fcm_registration_id},
        headers: {'Authorization' => Fcm_server_api_key,'Content-Type' => "application/json",charset: "UTF-8"})

    req.run
    response = req.response

    body = response.body

I keep getting following message in the response.body:

我一直在response.body中收到以下消息:

"JSON_PARSING_ERROR: Unexpected token END OF FILE at position 0."

The error message says clearly that sth with Json might be wrong and I tried already various combinations of supplying my Json and no success yet. I would be really grateful for any tips!

错误消息清楚地表明,使用Json可能是错误的,我已经尝试了各种组合供应我的Json但尚未成功。我会非常感谢任何提示!

1 个解决方案

#1


1  

I'm totally confused as to why sending Jsons to FCM doesn't work in Typhoeus but I finally managed to send successful request by changing Content-Type from application/json to plain text and sending my message in plain text format of course.

我完全感到困惑的是,为什么将Jsons发送到FCM在Typhoeus中不起作用但我终于设法通过将Content-Type从application / json更改为纯文本并以纯文本格式发送我的消息来发送成功请求。

Here's complete helper module I wrote for convenience:

这是我为方便起见编写的完整助手模块:

module FcmModule
  require 'typhoeus'
  require 'typhoeus/request'

  Fcm_server_api_key = 'key=<YOUR_SERVER_KEY>'
  Fcm_server_uri = 'https://fcm.googleapis.com/fcm/send'

  Status_message_sent = 0
  Status_failed = 1
  Status_not_registered = 2
  Status_update_registration_id = 3

  def send_notification_to_fcm(title, description, from_teacher,
                               notification_type_id, fcm_registration_id)

    req = Typhoeus::Request.new(
        Fcm_server_uri,
        method: :post,
        body: "registration_id=#{fcm_registration_id}&" +
            "data.myFromTeacher=#{from_teacher}&" +
            "data.myTitle=#{title}&" +
            "data.myDescription=#{description}&" +
            "data.myNotificationTypeId=#{notification_type_id}",

        headers: {'Authorization' => Fcm_server_api_key,'Content-Type' => "application/x-www-form-urlencoded",charset: "UTF-8"})

    req.run
    response = req.response

    body = response.body
    bodyResults = Hash[body.each_line.map { |l| l.chomp.split('=', 2) }]

    if !bodyResults['id'].nil? && !bodyResults['registration_id'].nil?
      return FcmResponse.new(bodyResults['id'], bodyResults['registration_id'], Status_update_registration_id)
    end

    if !bodyResults['Error'].nil?
      if bodyResults['Error'] == 'NotRegistered'
        return FcmResponse.new(nil, nil, Status_not_registered)
      else
        return FcmResponse.new(nil, nil, Status_failed)
      end
    else
      return FcmResponse.new(bodyResults['id'], nil, Status_message_sent)
    end

  end

  class FcmResponse

    def initialize(message_id, registration_id, status)
      @message_id = message_id
      @registration_id = registration_id
      @status = status
    end

    def message_id
      @message_id
    end

    def registration_id
      @registration_id
    end

    def status
      @status
    end

  end
end

Here's an example of using the module:

以下是使用该模块的示例:

fcm_response = send_notification_to_fcm('title','description', 'from_teacher', 1, fcm_registration_id)
        if fcm_response.status == Status_message_sent
          # todo save to our users notifications in database
        elsif fcm_response.status == Status_update_registration_id
          # todo update fcm_registration_id for given device with fcm_response.registration_id
        elsif fcm_response.status == Status_not_registered
          # todo delete given device from our database
        elsif fcm_response.status == Status_failed
          # todo return some error message to client to retry sending the notification
        end

EDIT:

Ekhm, well I couldn't let it go and looked at the code once more. In order to send a Json in post Typhoeus Request I had to provide the hash in "body" parameter, NOT "params". Here's working request for sending Json:

Ekhm,我不能放过它再一次看着代码。为了在Typhoeus请求后发送Json,我必须在“body”参数中提供哈希,而不是“params”。这是发送Json的工作请求:

req = Typhoeus::Request.new(
        Fcm_server_uri,
        method: :post,
        body: {'to' => fcm_registration_id}, # body instead of params!
        headers: {'Authorization' => Fcm_server_api_key,'Content-Type' => "application/json",charset: "UTF-8"})

    req.run
    response = req.response

    body = response.body

Now excuse me, I need to bang my head against a wall...

现在打扰一下,我需要把头靠在墙上......

#1


1  

I'm totally confused as to why sending Jsons to FCM doesn't work in Typhoeus but I finally managed to send successful request by changing Content-Type from application/json to plain text and sending my message in plain text format of course.

我完全感到困惑的是,为什么将Jsons发送到FCM在Typhoeus中不起作用但我终于设法通过将Content-Type从application / json更改为纯文本并以纯文本格式发送我的消息来发送成功请求。

Here's complete helper module I wrote for convenience:

这是我为方便起见编写的完整助手模块:

module FcmModule
  require 'typhoeus'
  require 'typhoeus/request'

  Fcm_server_api_key = 'key=<YOUR_SERVER_KEY>'
  Fcm_server_uri = 'https://fcm.googleapis.com/fcm/send'

  Status_message_sent = 0
  Status_failed = 1
  Status_not_registered = 2
  Status_update_registration_id = 3

  def send_notification_to_fcm(title, description, from_teacher,
                               notification_type_id, fcm_registration_id)

    req = Typhoeus::Request.new(
        Fcm_server_uri,
        method: :post,
        body: "registration_id=#{fcm_registration_id}&" +
            "data.myFromTeacher=#{from_teacher}&" +
            "data.myTitle=#{title}&" +
            "data.myDescription=#{description}&" +
            "data.myNotificationTypeId=#{notification_type_id}",

        headers: {'Authorization' => Fcm_server_api_key,'Content-Type' => "application/x-www-form-urlencoded",charset: "UTF-8"})

    req.run
    response = req.response

    body = response.body
    bodyResults = Hash[body.each_line.map { |l| l.chomp.split('=', 2) }]

    if !bodyResults['id'].nil? && !bodyResults['registration_id'].nil?
      return FcmResponse.new(bodyResults['id'], bodyResults['registration_id'], Status_update_registration_id)
    end

    if !bodyResults['Error'].nil?
      if bodyResults['Error'] == 'NotRegistered'
        return FcmResponse.new(nil, nil, Status_not_registered)
      else
        return FcmResponse.new(nil, nil, Status_failed)
      end
    else
      return FcmResponse.new(bodyResults['id'], nil, Status_message_sent)
    end

  end

  class FcmResponse

    def initialize(message_id, registration_id, status)
      @message_id = message_id
      @registration_id = registration_id
      @status = status
    end

    def message_id
      @message_id
    end

    def registration_id
      @registration_id
    end

    def status
      @status
    end

  end
end

Here's an example of using the module:

以下是使用该模块的示例:

fcm_response = send_notification_to_fcm('title','description', 'from_teacher', 1, fcm_registration_id)
        if fcm_response.status == Status_message_sent
          # todo save to our users notifications in database
        elsif fcm_response.status == Status_update_registration_id
          # todo update fcm_registration_id for given device with fcm_response.registration_id
        elsif fcm_response.status == Status_not_registered
          # todo delete given device from our database
        elsif fcm_response.status == Status_failed
          # todo return some error message to client to retry sending the notification
        end

EDIT:

Ekhm, well I couldn't let it go and looked at the code once more. In order to send a Json in post Typhoeus Request I had to provide the hash in "body" parameter, NOT "params". Here's working request for sending Json:

Ekhm,我不能放过它再一次看着代码。为了在Typhoeus请求后发送Json,我必须在“body”参数中提供哈希,而不是“params”。这是发送Json的工作请求:

req = Typhoeus::Request.new(
        Fcm_server_uri,
        method: :post,
        body: {'to' => fcm_registration_id}, # body instead of params!
        headers: {'Authorization' => Fcm_server_api_key,'Content-Type' => "application/json",charset: "UTF-8"})

    req.run
    response = req.response

    body = response.body

Now excuse me, I need to bang my head against a wall...

现在打扰一下,我需要把头靠在墙上......