fcmpush icon indicating copy to clipboard operation
fcmpush copied to clipboard

push method and batch_push method error handling compatibility

Open miyataka opened this issue 5 years ago • 2 comments

miyataka avatar Jul 13 '20 15:07 miyataka

Is there a clean way to extract error response messages?

When using batch_push it's straightforward as it does not raise an error:

client = Fcmpush.new('sample-project')
puts client.batch_push(payloads).json.inspect
# this will print
# [{:name=>"projects/sample-project/messages/1702368289437197"}] # if success
# [{:error=>{:code=>400, :message=>"The registration token is not a valid FCM registration token", :status=>"INVALID_ARGUMENT", :details=>[{:@type=>"type.googleapis.com/google.firebase.fcm.v1.FcmError", :errorCode=>"INVALID_ARGUMENT"}]}}] # if invalid token

But when using push, it raises an error:

client = Fcmpush.new('sample-project')
puts client.push(payload).json.inspect
# this will print
# {:name=>"projects/sample-project/messages/1702368289437197"} # if success
# but raises an `Fcmpush::BadRequest` if token failed

To extract the error response message, I have to:

response = 
  begin
    client.push(payload).json
  rescue Fcmpush::BadRequest => e
    JSON.parse(e.message.split(':', 2).last, :symbolize_names => true)
  end

# where `response` will either contain
# {:name=>"projects/sample-project/messages/1702368289437197"} # if success
# {:error=>{:code=>400, :message=>"The registration token is not a valid FCM registration token", :status=>"INVALID_ARGUMENT", :details=>[{:@type=>"type.googleapis.com/google.firebase.fcm.v1.FcmError", :errorCode=>"INVALID_ARGUMENT"}]}} # if invalid token

Is there a cleaner way to extract the error response message without e.message.split(':', 2).last?

The code in question: https://github.com/miyataka/fcmpush/blob/main/lib/fcmpush/client.rb#L141

Why am I doing this?

I received an email from Firebase about Your recent usage of impacted APIs/features: Batch send API which will stop working on June 20, 2024.

The official documentation suggests to just iterate the calls to HTTP V1:

For protocol, instead use the standard HTTP v1 API send method, implementing your own batch send by iterating through the list of recipients and sending to each recipient's token.

Also according to: https://groups.google.com/g/firebase-talk/c/4GuTzvRT_10

This means that if, for example, I send 400 FCM messages, I will trigger or contact the following URL 400 times in succession / row: https://fcm.googleapis.com/v1/projects/my-app/messages:send Your updated approach is the intended behavior.

So I'm migrating from batch_push to looping push.

To achieve the same output of client.batch_push(payloads).json, I have to:

payloads.map do |payload|
  begin
    client.push(payload).json
  rescue Fcmpush::BadRequest => e
    JSON.parse(e.message.split(':', 2).last, :symbolize_names => true)
  end
end

Thanks for the awesome library btw!

dcangulo avatar Dec 12 '23 08:12 dcangulo

Is there a cleaner way to extract the error response message without e.message.split(':', 2).last?

@dcangulo, you can do this:

begin
  client.push(payload).json
rescue Fcmpush::BadRequest => e
  JSON.parse(e.response.body)
end

Lego4m avatar Jan 30 '24 12:01 Lego4m