push method and batch_push method error handling compatibility
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!
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