WIP feat(fcm): Add support for AndroidConfigV2#968
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces V2 configurations for Android messaging in the Firebase Admin Python SDK, including AndroidConfigV2, AndroidNotificationV2, AndroidRemoteNotification, and AndroidBackgroundSyncMessage, while deprecating the older V1 equivalents. The feedback highlights an issue where vibrate_timings_millis is documented to support datetime.timedelta instances, but the implementation only validates numbers. To resolve this, the reviewer suggests adding a helper method to validate both types, updating the encoder, and adjusting the test suite to verify this behavior.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the new AndroidConfigV2 and its associated V2 classes (AndroidNotificationV2, AndroidRemoteNotification, and AndroidBackgroundSyncMessage) to the FCM messaging module, while deprecating the older AndroidConfig and AndroidNotification implementations. It includes comprehensive encoding, validation logic, and unit tests. The review feedback highlights a few validation improvements: specifically, explicitly rejecting boolean values in check_vibrate_timings (since Python treats bool as a subclass of int/numbers.Number) and ensuring that all boolean fields in AndroidNotificationV2 are properly validated using _Validators.check_boolean.
| non_valid = [ | ||
| k for k in value | ||
| if not isinstance(k, (numbers.Number, datetime.timedelta)) | ||
| ] |
There was a problem hiding this comment.
In Python, bool is a subclass of int (and thus numbers.Number). Therefore, isinstance(True, numbers.Number) evaluates to True. This means boolean values like True or False will incorrectly pass the check_vibrate_timings validation and be treated as valid vibrate timings (which are then encoded as 1s or 0s by encode_milliseconds). We should explicitly reject boolean values.
| non_valid = [ | |
| k for k in value | |
| if not isinstance(k, (numbers.Number, datetime.timedelta)) | |
| ] | |
| non_valid = [ | |
| k for k in value | |
| if isinstance(k, bool) or not isinstance(k, (numbers.Number, datetime.timedelta)) | |
| ] |
| 'sticky': notification.sticky, | ||
| 'event_time': _Validators.check_datetime( | ||
| 'AndroidNotificationV2.event_time', notification.event_time), | ||
| 'local_only': notification.local_only, |
There was a problem hiding this comment.
The fields sticky and local_only in AndroidNotificationV2 are boolean fields but are not validated using _Validators.check_boolean. To ensure type safety and prevent invalid types from being serialized and sent to the FCM backend, we should validate them.
'sticky': _Validators.check_boolean(
'AndroidNotificationV2.sticky', notification.sticky),
'event_time': _Validators.check_datetime(
'AndroidNotificationV2.event_time', notification.event_time),
'local_only': _Validators.check_boolean(
'AndroidNotificationV2.local_only', notification.local_only),| 'default_vibrate_timings': notification.default_vibrate_timings, | ||
| 'default_sound': notification.default_sound, | ||
| 'default_light_settings': notification.default_light_settings, |
There was a problem hiding this comment.
The fields default_vibrate_timings, default_sound, and default_light_settings in AndroidNotificationV2 are boolean fields but are not validated using _Validators.check_boolean. We should validate them to ensure type safety and prevent invalid types from being serialized.
| 'default_vibrate_timings': notification.default_vibrate_timings, | |
| 'default_sound': notification.default_sound, | |
| 'default_light_settings': notification.default_light_settings, | |
| 'default_vibrate_timings': _Validators.check_boolean( | |
| 'AndroidNotificationV2.default_vibrate_timings', notification.default_vibrate_timings), | |
| 'default_sound': _Validators.check_boolean( | |
| 'AndroidNotificationV2.default_sound', notification.default_sound), | |
| 'default_light_settings': _Validators.check_boolean( | |
| 'AndroidNotificationV2.default_light_settings', notification.default_light_settings), |
This change implements support for the Android v2 API and it deprecates v1 AndroidConfig structures and replaces them with the new AndroidConfigV2 structures.
Adds AndroidConfigV2, AndroidNotificationV2, AndroidRemoteNotification, and AndroidBackgroundSyncMessage data classes.
Deprecates AndroidConfig and AndroidNotification.