firebase / firebase/firebase-admin-go
Provide an interface for getting the cause of QUOTA_EXCEEDED
- Dominant language
- Go
- Stars
- 1.3k
- Forks
- 274
- Avg merge
- 10h 39m
- Merged PRs (30d)
- 2
Description
The QUOTA_EXCEEDED (HTTP error 429) is caused when a message rate quota is exceeded. According to https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode, there are three different reasons/ 'scenarios' where this happens:
> Message rate exceeded: The sending rate of messages is too high. You must reduce the overall rate at which you send messages. Use exponential backoff with a minimum initial delay of 1 minute to retry rejected messages.
> Device message rate exceeded: The rate of messages to a particular device is too high. See [message rate limit to a single device](https://firebase.google.com/docs/cloud-messaging/concept-options#device_throttling). Reduce the number of messages sent to this device and use exponential backoff to retry sending.
> Topic message rate exceeded: The rate of messages to subscribers to a particular topic is too high. Reduce the number of messages sent for this topic and use exponential backoff with a minimum initial delay of 1 minute to retry sending.
The documentation says that we can get the quota exceeded reason via a `google.rpc.QuotaFailure` structure:
> Sending limit exceeded for the message target. An extension of type `google.rpc.QuotaFailure` is returned to specify which quota was exceeded.
However, interface methods like `fcmClient.Send`[[1](https://github.com/firebase/firebase-admin-go/blob/26dec0b7589ef7641eefd6681981024079b8524c/messaging/messaging.go#L962)] only return the standard `error` type.
I suspect that the `QuotaFailure` is stored as a `FirebaseError` in the `Ext map[string]interface{}` or `Response *http.Reponse` attribute, but `FirebaseError` is internal and so integrators cannot/ should not access this.
https://github.com/firebase/firebase-admin-go/blob/26dec0b7589ef7641eefd6681981024079b8524c/internal/errors.go#L91
In this library, `http_client.go` handles the HTTP response results, where it casts as standard `error`s.
https://github.com/firebase/firebase-admin-go/blob/26dec0b7589ef7641eefd6681981024079b8524c/internal/http_client.go#L209:L211
### Feature Gap with the Firebase Python Library `firebase/firebase-admin-python`
We can see that this behaviour, of allowing integrators to handle `FirebaseError`, is available in the Python library firebase/firebase-admin-library, where it raises `FirebaseError` (or `ValueError`) accordingly.
https://github.com/firebase/firebase-admin-python/blob/d5aba8443196e0212d724bd7b81f73689b5c8a08/firebase_admin/messaging.py#L107:L125
So, we know that we should provide integrators with a way to access these custom error types.
## To Do
From the user caller's perspective (when falling `fcmClient.Send`), users who receive a 429 error code should be able to find which reason caused the error.
- [ ] To do this, the custom error types (in particular, `FirebaseError`) cannot be internal
- This is a duplicate of https://github.com/firebase/firebase-admin-go/issues/576
- PR: https://github.com/firebase/firebase-admin-go/pull/737
- [ ] There should be a helper method, like `QuotaExceededReason(err FirebaseError) QuotaFailure` or `QuotaExceededReason(err error) QuotaFailure`.
- PR: https://github.com/firebase/firebase-admin-go/pull/739
Contributor guide
Assessment
This issue has not been assessed yet.