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 );
scopeServiceWorkerRegistration.scope for a service worker subscription, or a unique URL (for example, chrome://my-module/push) for a system subscription.principalnsIPrincipal to associate with the subscription. Privileged code should pass the system principal.callbacknsIPushSubscription 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 );
scopensIPushService.subscribe().principalnsIPrincipal, as passed to nsIPushService.subscribe().callbacknsIPushSubscription.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 );
scopensIPushService.subscribe().principalnsIPrincipal, as passed to nsIPushService.subscribe().callbacknsIPushSubscription 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);