nsISupports
Last changed in Gecko 46.0 (Firefox 46.0 / Thunderbird 46.0 / SeaMonkey 2.43)Push lets a remote server send payloads to a web site, add-on, or component running in the browser. nsIPushService
supports the Push API implementation in Firefox, and can be used directly from privileged code to create system subscriptions.
Implemented by @mozilla.org/push/Service;1
as a service:
const pushService = Components.classes["@mozilla.org/push/Service;1"] .getService(Components.interfaces.nsIPushService);
void subscribe(in DOMString scope, in nsIPrincipal principal, in nsIPushSubscriptionCallback callback); |
void getSubscription(in DOMString scope, in nsIPrincipal principal, in nsIPushSubscriptionCallback callback); |
void unsubscribe(in DOMString scope, in nsIPrincipal principal, in nsIUnsubscribeResultCallback callback); |
Creates a push subscription.
void subscribe( in DOMString scope, in nsIPrincipal principal, in nsIPushSubscriptionCallback callback );
scope
ServiceWorkerRegistration.scope
for a service worker subscription, or a unique URL (for example, chrome://my-module/push
) for a system subscription.principal
nsIPrincipal
to associate with the subscription. Privileged code should pass the system principal.callback
nsIPushSubscription
is created.Passing the system principal exempts the subscription from permission checks and background messages quotas, which are enforced for service worker subscriptions.
const { classes: Cc, interfaces: Ci, utils: Cu } = Components; const scriptSecurityManager = Cc["@mozilla.org/scriptsecuritymanager;1"] .getService(Ci.nsIScriptSecurityManager); const pushService = Cc["@mozilla.org/push/Service;1"] .getService(Ci.nsIPushService); pushService.subscribe( "chrome://my-module/push", scriptSecurityManager.getSystemPrincipal(), (code, subscription) => { if (!Components.isSuccessCode(code)) { Cu.reportError("Error creating subscription: " + code); return; } // `subscription` implements `nsIPushSubscription`. subscription.endpoint; subscription.getKey("p256dh"); subscription.getKey("auth"); } );
Fetches an existing subscription.
void getSubscription( in DOMString scope, in nsIPrincipal principal, in nsIPushSubscriptionCallback callback );
scope
nsIPushService.subscribe()
.principal
nsIPrincipal
, as passed to nsIPushService.subscribe()
.callback
nsIPushSubscription
.pushService.getSubscription( "chrome://my-module/push", scriptSecurityManager.getSystemPrincipal(), (code, subscription) => { if (!Components.isSuccessCode(code)) { Cu.reportError("Error fetching subscription: " + code); return; } // `subscription == null` if the `(scope, principal)` pair doesn't have a // push subscription. Otherwise, it's an instance of `nsIPushSubscription`. } );
Drops an existing push subscription.
void unsubscribe( in DOMString scope, in nsIPrincipal principal, in nsIUnsubscribeResultCallback callback );
scope
nsIPushService.subscribe()
.principal
nsIPrincipal
, as passed to nsIPushService.subscribe()
.callback
nsIPushSubscription
is dropped.pushService.unsubscribe( "chrome://my-module/push", scriptSecurityManager.getSystemPrincipal(), (code, ok) => { if (!Components.isSuccessCode(code)) { Cu.reportError("Error unsubscribing: " + code); return; } // `ok === true` if the subscription was removed, or `false` if the // `(scope, principal)` pair didn't have a subscription. } );
Subscriptions created from privileged code use XPCOM observer notifications instead of service worker events. You can use the global nsIObserverService
to listen for these notifications.
Messages sent to system subscriptions are broadcasted to all push-message
observers. Your nsIObserver
should ensure the data
parameter matches your subscription scope. Otherwise, your code may try to handle messages meant for other subscriptions.
Topic | Subject | Data | Description | Push API Counterpart |
push-message |
nsIPushMessage if the message has a payload; null for blank messages. |
Scope | Fired when a push message is sent to a system subscription. | ServiceWorkerGlobalScope.onpush |
push-subscription-change |
null |
Scope | Fired when the Push server drops a subscription, or the subscription identifier changes. | ServiceWorkerGlobalScope.onpushsubscriptionchange |
Please make sure you listen for push-subscription-change
. If the subscription is lost, and your code isn't listening for this notification, you won't be able to receive messages until you create a new subscription.
const obsService = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); let pushObserver = { scope: "chrome://my-module/push", observe(subject, topic, data) { // The scope is passed as the `data` argument for `push-message` and // `push-subscription-change` observers. Make sure the message is meant // for us. if (data == this.scope) { if (topic == "push-message") { this.onPushMessage(subject); } else if (topic == "push-subscription-change") { this.onPushSubscriptionChange(); } } }, onPushMessage(maybeMessage) { if (!maybeMesssage) { // The subject will be `null` for messages without data. return; } let message = maybeMesssage.QueryInterface(Ci.nsIPushMessage); message.text(); // Returns the message contents as a UTF-8 string. message.json(); // Parses the message as JSON. message.binary(); // Returns a byte array. }, onPushSubscriptionChange() { // Re-subscribe if the subscription was dropped. pushService.subscribe( this.scope, scriptSecurityManager.getSystemPrincipal(), (code, subscription) => { // ... }); } }; obsService.addObserver(pushObserver, "push-message", false); obsService.addObserver(pushObserver, "push-subscription-change", false);