{"id":340487,"date":"2026-07-27T19:28:48","date_gmt":"2026-07-27T19:28:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/web-push-notifications-via-firebase\/"},"modified":"2026-08-05T22:07:20","modified_gmt":"2026-08-05T22:07:20","slug":"notifreach-push-notifications","status":"publish","type":"plugin","link":"https:\/\/tw.wordpress.org\/plugins\/notifreach-push-notifications\/","author":23532649,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2.0","stable_tag":"1.2.0","tested":"7.0.3","requires":"5.6","requires_php":"7.2","requires_plugins":null,"header_name":"NotifReach: Push Notifications","header_author":"ICodePlugins","header_description":"Sends Firebase push notifications and stores mobile phone as subscriber identifier for cross-plugin interoperability.","assets_banners_color":"697393","last_updated":"2026-08-05 22:07:20","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/icodeplugins.com\/","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":152,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"icodeplugins","date":"2026-07-27 19:28:37"},"1.1.0":{"tag":"1.1.0","author":"icodeplugins","date":"2026-08-03 11:53:00"},"1.2.0":{"tag":"1.2.0","author":"icodeplugins","date":"2026-08-05 22:07:20"}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3625222,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3625222,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.1.0","1.2.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3625222,"resolution":"1","location":"assets","locale":"","width":1920,"height":1080},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3625222,"resolution":"2","location":"assets","locale":"","width":1920,"height":1080},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3625222,"resolution":"3","location":"assets","locale":"","width":1920,"height":1080},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3625222,"resolution":"4","location":"assets","locale":"","width":1920,"height":1080},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3625222,"resolution":"5","location":"assets","locale":"","width":1920,"height":1080},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3625222,"resolution":"6","location":"assets","locale":"","width":1920,"height":1080},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3625222,"resolution":"7","location":"assets","locale":"","width":1920,"height":1080},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3625222,"resolution":"8","location":"assets","locale":"","width":1920,"height":1080}},"screenshots":{"1":"Send screen: filter your subscribers by campaign, location, role or device, select the recipients, and compose a rich notification.","2":"A push template bound to a WordPress hook, with the dynamic placeholders that hook exposes.","3":"Campaign editor: A\/B test with an audience split and auto-send of the winning variant, plus a live preview and action buttons.","4":"Campaign analytics: sent, failed, clicks, CTR, conversions and unsubscribes over the period.","5":"Subscribers Map: where your subscribers are, with cascading filters and a synchronised table.","6":"Connection settings: your own Google OAuth2 client and Firebase project configuration.","7":"The subscription modal as visitors see it, with content you edit in the WordPress block editor.","8":"Subscriber preference center: visitors turn individual campaigns on or off themselves."}},"plugin_section":[],"plugin_tags":[7644,143080,14432,1155,37677],"plugin_category":[],"plugin_contributors":[273537],"plugin_business_model":[],"class_list":["post-340487","plugin","type-plugin","status-publish","hentry","plugin_tags-campaigns","plugin_tags-fcm","plugin_tags-firebase","plugin_tags-push-notifications","plugin_tags-web-push","plugin_contributors-icodeplugins","plugin_committers-icodeplugins"],"banners":{"banner":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/banner-772x250.jpg?rev=3625222","banner_2x":false,"banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/icon-256x256.png?rev=3625222","icon_2x":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/icon-256x256.png?rev=3625222","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-1.png?rev=3625222","caption":"Send screen: filter your subscribers by campaign, location, role or device, select the recipients, and compose a rich notification."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-2.png?rev=3625222","caption":"A push template bound to a WordPress hook, with the dynamic placeholders that hook exposes."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-3.png?rev=3625222","caption":"Campaign editor: A\/B test with an audience split and auto-send of the winning variant, plus a live preview and action buttons."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-4.png?rev=3625222","caption":"Campaign analytics: sent, failed, clicks, CTR, conversions and unsubscribes over the period."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-5.png?rev=3625222","caption":"Subscribers Map: where your subscribers are, with cascading filters and a synchronised table."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-6.png?rev=3625222","caption":"Connection settings: your own Google OAuth2 client and Firebase project configuration."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-7.png?rev=3625222","caption":"The subscription modal as visitors see it, with content you edit in the WordPress block editor."},{"src":"https:\/\/ps.w.org\/notifreach-push-notifications\/assets\/screenshot-8.png?rev=3625222","caption":"Subscriber preference center: visitors turn individual campaigns on or off themselves."}],"raw_content":"<!--section=description-->\n<p>Send web push notifications to your visitors' browsers and devices using Firebase Cloud Messaging (FCM HTTP v1). Visitors opt in from the frontend with a single toggle button; from there you can notify them manually, automatically in response to any WordPress or plugin event, or through scheduled and recurring campaigns with click and conversion analytics. There are no subscriber or send limits \u2014 nothing here is metered by volume.<\/p>\n\n<p>Notifications are sent with <strong>your own Firebase project<\/strong>: you connect your Google OAuth2 client and your Firebase credentials, and your site talks to FCM directly. No third-party sending service sits in between.<\/p>\n\n<h4>Collecting subscribers<\/h4>\n\n<ul>\n<li><strong>Subscribe\/unsubscribe toggle button<\/strong> via shortcode, reflecting its state with <code>subscribed<\/code> \/ <code>unsubscribed<\/code> CSS classes.<\/li>\n<li><strong>Subscription modal<\/strong> whose content comes from a dedicated, translatable custom post type (\"Subscription modal templates\") edited with the native WordPress editor \u2014 not indexed on the frontend.<\/li>\n<li><strong>All subscription fields are optional and selectable<\/strong> (phone, email, first name, last name). Only the device token is required; an email is needed only if you want to create or link a WordPress user account.<\/li>\n<li><strong>Decoupled feedback messages<\/strong>: a feedback shortcode you can place anywhere, rendered inline, as native WordPress (Gutenberg) <strong>snackbar toasts<\/strong>, or both. A JavaScript event is also dispatched for fully custom rendering.<\/li>\n<li><strong>Placement and styling<\/strong> presets for the button and the modal (inline or fixed corners, accent colour, custom classes), with a shortcode builder and live preview in the settings.<\/li>\n<li><strong>Works with any form plugin or custom UI<\/strong>: bind the plugin to your own selectors, or trigger a subscription by dispatching the <code>icfp:external-subscribe<\/code> JavaScript event.<\/li>\n<li><strong>Resilient subscriptions<\/strong>: device tokens are refreshed automatically when they rotate, renewed subscriptions are recovered by the service worker, and dead tokens are pruned.<\/li>\n<\/ul>\n\n<h4>Sending notifications<\/h4>\n\n<ul>\n<li><strong>Send screen<\/strong> with a filterable, paginated <strong>recipient selector<\/strong> (filter by campaign, location, role, browser\/device; select across the whole filtered list) and a rich message composer: title, body, click URL with a page\/post picker, icon, badge, hero image, media pickers, live preview, and <strong>action buttons<\/strong> that each open their own URL.<\/li>\n<li><strong>Hook-triggered notifications<\/strong>: build notification templates (custom post type) bound to any WordPress or plugin action hook, with dynamic placeholders resolved from the hook arguments. A hook knowledge base and a plugin hook scanner help you find the right event.<\/li>\n<li><strong>Ready-made templates<\/strong> are bundled with the plugin and installed on activation. You can also <strong>import a template from a <code>.json<\/code> file<\/strong> (file picker or drag &amp; drop) from the Push Templates screen; duplicate and near-duplicate templates are detected on import.<\/li>\n<li><strong>Multilingual routing<\/strong>: the subscriber's language is stored and matched to the template language (Polylang \/ WPML aware).<\/li>\n<\/ul>\n\n<h4>Campaigns<\/h4>\n\n<ul>\n<li><strong>Three campaign types<\/strong>: permanent (send on demand), scheduled (one-off, with optional daily\/weekly\/monthly recurrence), or triggered by a WordPress event.<\/li>\n<li><strong>Audience targeting<\/strong> by user role, by anonymous visitors (subscribers with no account), by language, or by an explicit list of subscribers.<\/li>\n<li><strong>A\/B testing<\/strong>: two variants, a configurable audience split, and optional auto-send of the higher-CTR variant to the rest of the audience.<\/li>\n<li><strong>UTM parameters and conversion goals<\/strong> on the click URL, with click and conversion tracking.<\/li>\n<li><strong>Frequency capping<\/strong>: cap how many pushes a subscriber can receive within a rolling window.<\/li>\n<li><strong>Test send<\/strong> to your own devices before sending to the full audience.<\/li>\n<\/ul>\n\n<h4>Measuring and managing<\/h4>\n\n<ul>\n<li><strong>Campaign Analytics<\/strong>: subscribers, active devices, sent, failed, clicks, CTR, conversions, CVR and unsubscribes, filterable by period, granularity, role and campaign, with CSV export.<\/li>\n<li><strong>Subscribers Map<\/strong>: an optional geolocation captured at subscription time, reverse-geocoded via OpenStreetMap, shown on a map with cascading filters (continent, country, region, postcode, role, browser, device) and a synchronised table.<\/li>\n<li><strong>Subscriber preference center<\/strong>: a frontend page where visitors opt in or out of individual campaigns, subscribe on the spot, or unsubscribe.<\/li>\n<li><strong>Passwordless account link<\/strong>: subscribers with a linked account receive a login link by push (delivered instantly) and, optionally, by email.<\/li>\n<\/ul>\n\n<h4>Reliable scheduling<\/h4>\n\n<p>Scheduled and recurring campaigns run through <strong>WP-Cron<\/strong>, a <strong>server crontab<\/strong>, or an external service such as <strong>cron-job.org<\/strong> calling the plugin's cron endpoint.<\/p>\n\n<h4>GDPR-ready<\/h4>\n\n<ul>\n<li><strong>Consent banner<\/strong>: a first-visit banner (on\/off, with fully editable and translatable text) asking visitors to accept or decline non-essential campaign-tracking cookies and geolocation capture. Declining never blocks the subscription itself.<\/li>\n<li><strong>Built into WordPress's own privacy tools<\/strong>: subscriber data is exportable and erasable from Tools \u2192 Export\/Erase Personal Data like any other personal data on your site \u2014 no separate privacy plugin required.<\/li>\n<li><strong>Self-service data requests<\/strong>: visitors can request an export or deletion of their own data straight from the subscriber preference center, without needing site-admin access.<\/li>\n<li><strong>Subscribers screen<\/strong>: search any subscriber by phone, email or linked account name and erase them on demand, with the option to also remove their linked WordPress user account.<\/li>\n<\/ul>\n\n<h4>Developer-friendly<\/h4>\n\n<p>No coding required for the core experience \u2014 shortcodes, visual template editors and point-and-click settings get you running. For teams who want to go further:<\/p>\n\n<ul>\n<li>A public PHP API (<code>ICodePlugins\\FirebasePush\\API<\/code>) for sending, managing subscribers and reading metrics.<\/li>\n<li>Authenticated <strong>REST routes<\/strong> under <code>icfp\/v1<\/code> (usable with WordPress Application Passwords) to send notifications, run campaigns, read metrics and manage subscribers.<\/li>\n<li>Actions and filters throughout \u2014 <code>icfp_subscriber_recorded<\/code>, <code>icfp_save_subscriber<\/code>, <code>icfp_delete_subscriber<\/code>, <code>icfp_rest_capability<\/code>, <code>icfp_webpush_urgency<\/code>, and more.<\/li>\n<li><strong>Fully translatable<\/strong> (text domain matches the plugin slug; an up-to-date <code>.pot<\/code> is included in <code>\/languages<\/code>; translations are provided via translate.wordpress.org).<\/li>\n<\/ul>\n\n<h4>Shortcodes<\/h4>\n\n<ul>\n<li><code>[icodeplugins_firebase_subscribe_btn]<\/code> \u2014 the subscribe\/unsubscribe toggle button. Optional attributes: <code>label<\/code>, <code>class<\/code>, <code>parent<\/code> (CSS selector to move the button into), <code>modal<\/code> (target a specific modal template by ID or slug).<\/li>\n<li><code>[icodeplugins_firebase_subscribe_feedback]<\/code> \u2014 the feedback region. Optional attributes: <code>class<\/code>, <code>parent<\/code>, <code>display<\/code> = <code>inline<\/code> (default), <code>toast<\/code>, or <code>both<\/code>.<\/li>\n<li><code>[icodeplugins_firebase_subscribe_assets]<\/code> \u2014 loads the subscription assets on a page that renders its own custom subscribe UI.<\/li>\n<li><code>[icodeplugins_notification_preferences]<\/code> \u2014 the subscriber preference center.<\/li>\n<\/ul>\n\n<h4>How it works<\/h4>\n\n<p>Subscriptions are created in the browser using the Firebase JavaScript SDK and a Web Push VAPID key; the resulting FCM device token is stored in your site database, together with whichever optional fields you chose to collect. To deliver a notification, the site authenticates to Google with your own OAuth2 client and calls the FCM HTTP v1 API.<\/p>\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/icodeplugins.com\/en\/downloads\/notifreach-web-push-notifications\/\">Get NotifReach Pro<\/a><\/p>\n\n<h3>External services<\/h3>\n\n<p>Web push cannot work without a push service: the browser vendors require one, and this plugin uses <strong>Google Firebase Cloud Messaging (FCM)<\/strong>, with the Firebase project <strong>you<\/strong> own and configure. Two further services (OpenStreetMap) are used only by the optional Subscribers Map.<\/p>\n\n<p>This plugin connects to the following third-party services.<\/p>\n\n<p><strong>1. Firebase Cloud Messaging \u2014 HTTP v1 API (Google)<\/strong>\nHosts: <code>https:\/\/fcm.googleapis.com<\/code>\nWhat it is \/ why: the push service that actually delivers notifications to your subscribers' browsers. It is required for the plugin to send anything at all.\nData sent, and when: <strong>every time a notification is sent<\/strong> (manually, by a campaign, or by a hook-triggered template), the plugin sends the message content (title, body, icon\/badge\/image URLs, click URL, action buttons) together with the recipient's FCM device token. No other subscriber data (email, phone, name, coordinates) is ever sent.\nTerms of service: https:\/\/firebase.google.com\/terms\/ \u2014 Privacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<p><strong>2. Google OAuth 2.0 \/ Google APIs (Google)<\/strong>\nHosts: <code>https:\/\/accounts.google.com<\/code>, <code>https:\/\/oauth2.googleapis.com<\/code>, <code>https:\/\/www.googleapis.com<\/code>\nWhat it is \/ why: authenticates your site to your own Firebase project, so it can call the FCM API above.\nData sent, and when: when the administrator clicks \"Connect Google Account\" (browser redirect to Google), then whenever an access token must be issued or refreshed before a send, and once more if the administrator clicks \"Disconnect\" (token revocation). Only your own OAuth client ID\/secret and the authorization\/refresh tokens are exchanged. No subscriber data is involved.\nTerms of service: https:\/\/policies.google.com\/terms \u2014 Privacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<p><strong>3. Firebase JavaScript SDK (Google)<\/strong>\nHosts: <code>https:\/\/firebaseinstallations.googleapis.com<\/code>, <code>https:\/\/fcmregistrations.googleapis.com<\/code> (contacted by the SDK; the SDK files themselves are bundled with the plugin and served from your own domain).\nWhat it is \/ why: runs in the visitor's browser and in the service worker to register the browser with FCM and obtain the device token that identifies it.\nData sent, and when: <strong>only when a visitor chooses to subscribe<\/strong> (and afterwards, if the browser rotates the token). The browser sends your Firebase project identifiers, your Web Push VAPID public key and the browser's push subscription details to Google. Nothing is sent for visitors who never subscribe.\nTerms of service: https:\/\/firebase.google.com\/terms\/ \u2014 Privacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<p><strong>4. Nominatim \u2014 reverse geocoding (OpenStreetMap Foundation)<\/strong>\nHost: <code>https:\/\/nominatim.openstreetmap.org<\/code>\nWhat it is \/ why: turns the coordinates a subscriber agreed to share into a readable address (country, region, postcode) for the optional Subscribers Map.\nData sent, and when: <strong>only if a visitor explicitly grants the browser's location permission when subscribing.<\/strong> The plugin then sends those coordinates (latitude\/longitude) and an identifying User-Agent, once per subscriber. If permission is denied \u2014 or the browser prompt is dismissed \u2014 nothing is collected and nothing is sent. No personal detail (email, phone, name, device token) is sent.\nTerms of service: https:\/\/osmfoundation.org\/wiki\/Terms_of_Use \u2014 Nominatim usage policy: https:\/\/operations.osmfoundation.org\/policies\/nominatim\/ \u2014 Privacy policy: https:\/\/osmfoundation.org\/wiki\/Privacy_Policy<\/p>\n\n<p><strong>5. OpenStreetMap map tiles (OpenStreetMap Foundation)<\/strong>\nHost: <code>https:\/\/tile.openstreetmap.org<\/code>\nWhat it is \/ why: supplies the background map images of the Subscribers Map screen. (The map library, Leaflet, is bundled with the plugin \u2014 it is not loaded from a CDN.)\nData sent, and when: only when an administrator opens the <strong>Subscribers Map<\/strong> admin screen, and only what any image request carries \u2014 the administrator's IP address and browser user-agent. No visitor or subscriber data is sent. No tile is requested on the front end.\nTile usage policy: https:\/\/operations.osmfoundation.org\/policies\/tiles\/ \u2014 Privacy policy: https:\/\/osmfoundation.org\/wiki\/Privacy_Policy<\/p>\n\n<h4>Privacy and consent<\/h4>\n\n<ul>\n<li>The plugin does <strong>not<\/strong> track visitors, does not profile them and contains no analytics. Nothing is collected from a visitor who does not subscribe.<\/li>\n<li>Subscribing is always an explicit action: the visitor clicks the subscribe button and then grants the browser's own notification permission.<\/li>\n<li>Geolocation is <strong>opt-in twice<\/strong>: the feature is optional for you, and the visitor must grant the browser's location permission. Refusing changes nothing else \u2014 the subscription still works.<\/li>\n<li>The subscriber's browser\/device (from the user-agent) is recorded on your own server to display it in the Subscribers Map. It is never sent to a third party.<\/li>\n<li>Subscriber details (email, phone, name, coordinates, addresses) are <strong>stored on your own site only<\/strong>, in your own database, and are deleted with the plugin's data when you uninstall it.<\/li>\n<li>Clicks and conversions are counted per campaign for your analytics; they are stored on your site only.<\/li>\n<\/ul>\n\n<p>Please make sure your site's privacy policy reflects the use of Firebase\/Google (and OpenStreetMap, if you enable the Subscribers Map).<\/p>\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/icodeplugins.com\/docs\/notifreach\/\">Read the full documentation<\/a><\/p>\n\n<p>Included in the Pro version:<\/p>\n\n<ul>\n<li>Set the push notification service in 2 clicks<\/li>\n<li>Real Linux CRON jobs for reliable delivery in a couple clicks<\/li>\n<li>Download and share push notification templates<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin to <code>\/wp-content\/plugins\/<\/code> and activate it.<\/li>\n<li>In <strong>NotifReach \u2192 Settings \u2192 Connection<\/strong>, enter your Firebase configuration (Project ID, API Key, App ID, Messaging Sender ID, Auth Domain), the Web Push <strong>VAPID key<\/strong>, and connect your <strong>Google OAuth2<\/strong> client (Client ID \/ Client Secret).<\/li>\n<li>Under <strong>Settings \u2192 Subscription fields<\/strong>, choose which optional fields to collect.<\/li>\n<li>Create at least one <strong>Subscription modal template<\/strong> (the content shown inside the subscribe modal).<\/li>\n<li>Add <code>[icodeplugins_firebase_subscribe_btn]<\/code> to a page or template, and optionally <code>[icodeplugins_firebase_subscribe_feedback]<\/code> near it. (The Integration tab can also render them for you.)<\/li>\n<li>(Optional) Create <strong>Push Templates<\/strong> bound to the hooks you want to trigger notifications, or start from the bundled ones.<\/li>\n<li>(Optional) Create a page with <code>[icodeplugins_notification_preferences]<\/code> so subscribers can manage their notifications.<\/li>\n<\/ol>\n\n<p>Your site must be served over <strong>HTTPS<\/strong> for web push to work.<\/p>\n\n<p><a rel=\"noopener noreferrer\" href=\"https:\/\/icodeplugins.com\/docs\/notifreach\/\">Read the full documentation<\/a><\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20an%20email%20address%20required%20to%20subscribe%3F\"><h3>Is an email address required to subscribe?<\/h3><\/dt>\n<dd><p>No. Every subscription field \u2014 phone number, email, first name, last name \u2014 is optional and you choose which ones to show. Only the browser's push token is required to receive notifications. Providing an email lets NotifReach create or link a WordPress user account for the subscriber, which unlocks the passwordless account link (a one-click login sent by push or email).<\/p><\/dd>\n<dt id=\"do%20i%20need%20a%20firebase%20account%3F\"><h3>Do I need a Firebase account?<\/h3><\/dt>\n<dd><p>Yes. Notifications are sent with your own Firebase project and your own Google OAuth2 client, both of which you configure in the Connection settings.<\/p><\/dd>\n<dt id=\"my%20scheduled%20campaigns%20go%20out%20late.%20why%3F\"><h3>My scheduled campaigns go out late. Why?<\/h3><\/dt>\n<dd><p>WP-Cron only runs when someone visits your site, so a low-traffic site fires it late. Use a real server crontab, or an external service such as cron-job.org, to call the plugin's cron endpoint on a fixed schedule.<\/p><\/dd>\n<dt id=\"why%20don%27t%20role-targeted%20campaigns%20reach%20most%20of%20my%20subscribers%3F\"><h3>Why don't role-targeted campaigns reach most of my subscribers?<\/h3><\/dt>\n<dd><p>Filtering by user role only reaches subscribers linked to a WordPress account. Most visitors subscribe anonymously, so tick <strong>Anonymous (no user account)<\/strong> in the campaign's Audience box, alone or alongside roles. Leaving everything unchecked targets all subscribers.<\/p><\/dd>\n<dt id=\"a%20notification%20was%20accepted%20but%20did%20not%20appear%20on%20brave%20%28mobile%29.%20why%3F\"><h3>A notification was accepted but did not appear on Brave (mobile). Why?<\/h3><\/dt>\n<dd><p>Brave on Android disables Google services for push messaging by default. Enable \"Use Google services for push messaging\" in Brave's settings, restart Brave, then subscribe again. On iOS, web push requires iOS 16.4+ and the site to be installed to the Home Screen (PWA).<\/p><\/dd>\n<dt id=\"does%20it%20support%20translations%3F\"><h3>Does it support translations?<\/h3><\/dt>\n<dd><p>Yes. The plugin is fully internationalized; a <code>.pot<\/code> file is provided in <code>\/languages<\/code>, and translations are handled via translate.wordpress.org. Subscriber and template languages are matched, with Polylang \/ WPML support.<\/p><\/dd>\n<dt id=\"is%20https%20required%3F\"><h3>Is HTTPS required?<\/h3><\/dt>\n<dd><p>Yes. Browsers only allow web push and service workers on secure origins.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Fixed duplicate notifications when WordPress fires more than one hook for the same action (e.g. <code>draft_to_publish<\/code> and <code>publish_post<\/code> both firing when a draft is published), including when a Campaign and a Template were both bound to it. Every Push Template now has its own \"also send its own notification when its trigger fires\" toggle, decoupled from its Published\/Draft status, so its content stays usable by a Campaign without also firing on its own \u2014 see the new Active Triggers screen (NotifReach \u2192 Active Triggers) for an at-a-glance view of every hook currently bound to a Template and\/or a Campaign.<\/li>\n<li>Fixed notifications incorrectly firing when editing or republishing the plugin's own admin content (Templates, Campaigns, Subscription modals, Consent banner text), since generic hooks like <code>draft_to_publish<\/code> fire for every post type, not just real site content.<\/li>\n<li>Added stronger duplicate-send protection for hook-triggered Templates and event-triggered Campaigns against a hook firing more than once for what feels like a single action (e.g. the block editor's autosave and publish requests landing on the same hook in separate requests), and client-side de-duplication for the rare case a push is otherwise delivered twice to the same device.<\/li>\n<li>Event-triggered Campaigns can now use dynamic <code>{post.X}<\/code>-style placeholders in their message (title, body, icon, image, click URL, action button URLs), resolved from the triggering event \u2014 the same placeholder syntax already available in hook-triggered Templates. Clicking a link in such a notification now reliably lands on the destination that was resolved at send time.<\/li>\n<li>Added the <code>{argName.featured_image}<\/code> placeholder \u2014 the triggering post's featured image URL, available for hook-triggered Templates and event-triggered Campaigns alike, including for native WordPress hooks.<\/li>\n<li>Performance fix: selecting a native WordPress hook (not tied to a specific plugin) in the template\/campaign trigger picker no longer scans every installed plugin's files.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>GDPR-ready: a first-visit consent banner (on\/off, fully editable and translatable text) gates non-essential campaign-tracking cookies and geolocation capture; subscriber data is exportable and erasable from WordPress's own Tools \u2192 Export\/Erase Personal Data; visitors can request their own data export\/erasure from the preference center; a new Subscribers screen lets admins search and erase subscribers on demand, with the option to also remove their linked WordPress user account.<\/li>\n<li>Auto-open subscription modal: trigger the modal automatically, with or without a visible button, after a load delay or a period of inactivity, and\/or once the visitor scrolls past a threshold \u2014 with a configurable reappearance policy (once per session, cooldown in days, or every time).<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: web push notifications via Firebase Cloud Messaging (FCM HTTP v1), sent with your own Firebase project and Google OAuth2 client.<\/li>\n<li>Frontend subscribe\/unsubscribe toggle button and translatable subscription modal (custom post type), with every subscription field optional.<\/li>\n<li>Feedback shortcode with inline and native WordPress snackbar toast rendering, plus a JavaScript event for custom UIs and form plugins.<\/li>\n<li>Send screen: filterable, paginated recipient selector and a rich message composer (icon, badge, hero image, action buttons, live preview).<\/li>\n<li>Hook-triggered notification templates with dynamic placeholders, a WordPress hook knowledge base and a plugin hook scanner. Bundled ready-made templates; import more from a <code>.json<\/code> file, with duplicate detection.<\/li>\n<li>Campaigns: permanent, scheduled\/recurring and event-triggered, with audience targeting, A\/B testing, UTM and conversion goals, frequency capping and test sends.<\/li>\n<li>Campaign Analytics with CSV export, and a Subscribers Map with geolocation and segmentation filters.<\/li>\n<li>Subscriber preference center and passwordless account link (by push and, optionally, by email).<\/li>\n<li>Multilingual routing (Polylang \/ WPML aware), a public PHP API and authenticated REST routes under <code>icfp\/v1<\/code>.<\/li>\n<\/ul>","raw_excerpt":"Web push notifications via Firebase (FCM): subscribe widget, hook-triggered templates, campaigns with A\/B testing and analytics, and a subscriber map.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/340487","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=340487"}],"author":[{"embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/icodeplugins"}],"wp:attachment":[{"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=340487"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=340487"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=340487"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=340487"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=340487"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/tw.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=340487"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}