Notifications/Developer guide/Push

Push notification support was added to the Echo extension in version 1.36.0. The implementation is documented here.

Overview
Push notification support is implemented as a third  notifier type alongside the previously existing   and   types. The  notifier, implemented in the   class, handles notifications by enqueuing an   job to query the DB for any registered push subscriptions associated with the recipient's global user ID. Push notification requests are sent to an external service (see mediawiki/services/push-notifications) for each subscription found. As currently implemented, the notification requests contain only a generic message intended to prompt the recipient app to "phone home" to the MediaWiki API's notifications module to retrieve full message content.

It is the client's responsibility to register users' push subscriptions via the echopushsubscriptions API module and update their notification preferences in order to benefit from push notifications.

As of September 2020, only app push notifications are supported, via Firebase Cloud Messaging (FCM) for Android and Apple Push Notification Service (APNS) for iOS. In the future (prospectively Q2 FY2020-2021) Echo will be updated to handle web push.

Config variables

 * : Whether push functionality will be enabled. If false, the push notifier type, the  API module, and the push notification preferences column will be suppressed. (Default:  )
 * : Base URL for the Echo push service. (Default: )
 * : The maximum number of subscriptions that may be associated with a global user ID. (Default: )

Subscription registration
Clients can create and delete subscriptions using the echopushsubscriptions API module. Subscriptions are associated with a user's global user ID. It is preferred that clients create subscriptions on login and delete them on logout. The maximum number of subscriptions per global user ID is defined in. Currently (as of September 2020), the maximum at Wikimedia is 10.

When the push service receives a response from a push provider API indicating that a token is invalid, it will make a request to the MediaWiki to delete the subscription associated with the token. This is not yet fully implemented; follow T260247 and subtasks for the current status of that work.

Updating notification preferences via API
User notification preferences are stored along with all other user preferences in the core user_properties table. This table is essentially a generic key-value store. Clients can manage user preferences stored in this table using the options API module. Notification preference keys are structured according to the convention  and the possible values are   (true) and   (false). Notifier types include,  , and (if enabled)  , and event category strings can be found in MediaWiki core and in the various extensions in which they are implemented.

As an example, the preference key name governing push notifications when the user is thanked for an edit would be. Accordingly, to enable push notifications via API, a client could submit the following request: /w/api.php?action=options&optionname=echo-subscriptions-push-edit-thank&optionvalue=1&token=ABC123 Note: These preferences are wiki-specific.

Data model
The main data store for this feature is the push subscriptions table. The subscription data includes push provider IDs and (optional) APNS topic IDs which are normalized to  and , respectively. Echo interacts with these latter tables through the core NameTableStore (T216468) interface.

At Wikimedia, the  tables are hosted in the   database in the   (x1) cluster.

TODO: Document the current DB schema

Quirks and gotchas
The  and   notifier types are defined and configured entirely in Echo's extension.json. In constrast, the push notifier type currently must be configured locally in  or in   and   at Wikimedia. This is to support conditionally enabling push by wiki. As of September 2020, in Wikimedia production, Echo push is only enabled on the Wikipedias. If and when Echo push is rolled out to all Wikis, this configuration can be moved to extension.json.