android icon indicating copy to clipboard operation
android copied to clipboard

Introduce PushProvider interface for push notification providers

Open lone-faerie opened this issue 9 months ago • 7 comments

Summary

This PR introduces a generic interface for push notification providers. Currently, the only provider is FCM, but an interface allows supporting additional push providers in the future, such as UnifiedPush.

The implementation is based on the SensorManager as only one instance of each provider is needed but they should still be able to be enabled for only a subset of servers. A PushManager class has also been added to coordinate the various push providers, which is currently just hard coded to use FCM but would provide the primary API for managing push providers.

Checklist

  • [x] New or updated tests have been added to cover the changes following the testing guidelines.
  • [x] The code follows the project's code style and best_practices.
  • [x] The changes have been thoroughly tested, and edge cases have been considered.
  • [x] Changes are backward compatible whenever feasible. Any breaking changes are documented in the changelog for users and/or in the code for developers depending on the relevance.

Any other notes

This came as a suggestion in this PR for adding UnifiedPush as an alternative push provider.

lone-faerie avatar May 11 '25 20:05 lone-faerie

Multiple comments aren't addressed. Please take a look to them before asking for re-review. Also I would like @jpelgrom opinion on the architecture since he was the one initially thinking about introducing this concept. So take a look to my comments and ask us to review again your changes :)

TimoPtr avatar May 21 '25 08:05 TimoPtr

How do you imagine UnifiedPush would work with this architecture for choosing between multiple distributors? The current architecture forces each push provider to have a separate class, while my first expectation would be that each distributor could be considered a push provider (for example, you get a list: none / FCM / ntfy / Sunup / ...).

jpelgrom avatar May 22 '25 22:05 jpelgrom

The reason for each push provider having its own class is to support multiple protocols, as well as helping to separate things between minimal and full. Like @TimoPtr said, it's a good idea to keep any references to FCM out of minimal. And all of the UnifiedPush distributors (ntfy, Sunup, etc.) would be covered under one class since they all use the same protocol.

The PushProvider interface is primarily for translating the various protocols into a common interface. For example, Firebase messages are received as a map but UnifiedPush messages are received as raw bytes, and Firebase just provides a token while UnifiedPush provides a url and public key. The PushManager class would then be responsible for coordinating the various push providers. It will provide the list of available providers/distributors as well as handling enabling the selected one.

As for the UI aspect of choosing a distributor, I imagined a setting similar to what I had in my previous PR though more generic to include other push providers apart from just UnifiedPush. This architecture would also open up the possibility of using a different provider for each server.

lone-faerie avatar May 23 '25 00:05 lone-faerie

I understand the advantages and was the one suggesting a generic interface on your previous PR. But how would this setup work for for choosing a distributor, which is a concept specific to UnifiedPush, if the other parts of the app don't know about them as the provider interface doesn't have a way to expose it?

(I tried do something similar for my UP proof of concept, though that has flaws in other ways, so I might simply be looking for something that you didn't add for a good reason and it hasn't clicked yet.)

jpelgrom avatar May 23 '25 18:05 jpelgrom

Ok, I get what you're saying. I was planning on initially just using the default UnifiedPush distributor with UnifiedPush.tryUseCurrentOrDefaultDistributor(context) just to get things working at first. But there's a couple ways I could see for the user choosing a distributor. We could add a getDistributors() method to PushProvider or the UnifiedPush library includes its own dialog for choosing a distributor that we could use.

lone-faerie avatar May 23 '25 23:05 lone-faerie

We could add a getDistributors() method to PushProvider

That could be an option. What would you return for that function in the FCM push provider?

or the UnifiedPush library includes its own dialog for choosing a distributor

That would require specific UI work outside the provider so kind of defeats the point, I think?

jpelgrom avatar May 26 '25 17:05 jpelgrom

That could be an option. What would you return for that function in the FCM push provider?

For the FCM provider, I'd either return null or "FCM" (or "Firebase"). If we allow null, then we could display it to the user as 'Provider (Distributor)' if not null, otherwise just 'Provider'. So for example, 'FCM' and 'UnifiedPush (ntfy)'. If getDistributor() always returns a list, so FCM returns "FCM", then we'd just display to the user each distributor.

That would require specific UI work outside the provider so kind of defeats the point, I think?

For UnifiedPush, the library handles the UI work, though for other providers, yeah it would require work outside of it. The library's UI probably doesn't align with Home Assistant's, so it's probably not the right choice, just wanted to mention it.

lone-faerie avatar May 27 '25 02:05 lone-faerie

@lone-faerie Are you still interested in working on this? In case it wasn't obvious with the 👍 reaction to your latest comment, your suggestion sounded OK to me. If you have any questions, feel free to ask. I'll change this to draft for now, whenever you're ready you can mark it as ready for review.

jpelgrom avatar Jun 23 '25 20:06 jpelgrom

Yeah, sorry I've been moving so haven't had any time to work on this. I'm finally settled in so I'll start up on this again soon

lone-faerie avatar Jul 02 '25 21:07 lone-faerie