The permission prompt at first launch
With askforpushpermissionatfirstrun set to true, iOS asks before users have seen anything. Users who tap Allow agreed to notifications, not to marketing.
App Store rejection
Apple allows marketing push notifications only after users explicitly opt in through consent text in your app, and only if they can opt out inside the app. The iOS permission dialog is not that consent. Here is how to separate transactional and marketing push, collect consent in your web app and connect it to the WebViewGold push setup.
From $109 one-time per platform, or let our team do it all from $698.
Guideline 4.5.4 sets four rules for push notifications. The app must work without them. They should not carry sensitive personal or confidential information. They should not be used for promotions or direct marketing unless the user has explicitly opted in through consent language shown in your app's interface. And the app must offer a way to opt out of those messages. Apple adds that abuse can cost you your push privileges.
Note what is not required: messages the user expects, such as "your order shipped" or "you have a new reply", need no extra consent beyond the system permission. The opt-in is specifically about promotions and marketing. The push notifications overview covers the general setup.
Reviewers usually say that the app uses, or appears to plan to use, push notifications for promotional purposes without explicit consent, or that there is no way to opt out in the app. They find this in the description ("get exclusive deals by push"), in an onboarding screen that promises offers, or in a test notification. A second variant says the app requires users to allow notifications before they can continue, which conflicts with the first sentence of 4.5.4.
With askforpushpermissionatfirstrun set to true, iOS asks before users have seen anything. Users who tap Allow agreed to notifications, not to marketing.
AI-generated onboarding often blocks the next step until permission is granted. That makes push required, which 4.5.4 does not allow.
The local push example in the WebViewGold docs is a cart reminder via sendlocalpushmsg://. Useful, but promotional: send it only to users who opted in to marketing.
firebaseTopic in Config.swift subscribes the app to one Firebase topic, so every install with Firebase push is in it. Fine for service notices; using it for promotions sends marketing to people who never opted in.
Descriptions and onboarding screens written by an AI love "never miss a special offer". Reviewers read that as a marketing plan without consent.

Great work! Never coded anything but managed to work with this. Easy and fast! Also with great help from the creators!
| Message | Type | Needs marketing opt-in |
|---|---|---|
| Your order has shipped | Transactional | No |
| Anna replied to your comment | Activity the user follows | No |
| Reminder the user set (workout at 7:00) | Requested by the user | No |
| Price alert the user created for a product | Requested by the user | No |
| 20% off this weekend | Promotion | Yes |
| Your cart is waiting | Promotion | Yes |
| We miss you, come back for a free credit | Re-engagement marketing | Yes |
| New feature: dark mode is here | Product news | Treat it as marketing |
Works with OneSignal, Firebase and Pushwoosh; the consent lives in your own database.
Set askforpushpermissionatfirstrun to false in Config.swift (on Android, requirePush to false in Config.java). The push notification docs describe both options.
After sign-up or the first meaningful action, explain what you will send. Offer two separate choices: "Order and account updates" and "Offers and news". The marketing choice is off by default and comes with its own consent sentence.
When the user switches on either choice, navigate to registerpush:// and iOS shows its permission dialog right then, in context. On Android, this requires at least one push service enabled in Config.java.
Read the subscription ID: getonesignalplayerid:// fills onesignalplayerid, getfirebaseplayerid:// fills firebaseplayerid, getpushwooshid:// fills pushwooshplayerid. For OneSignal and Firebase, autoInjectVariable set to true injects the ID automatically. Save it with the user's choices, the consent text version and a timestamp, and mention push tokens in your privacy policy (privacy policy and labels guide).
Your backend selects recipients from the database: OneSignal's API can target specific subscription IDs, and Firebase can send to individual tokens or to a topic your server subscribes opted-in tokens to. Never use the shared firebaseTopic for promotions. The push provider comparison explains the targeting options of each service.
An "Offers and news" toggle in your settings page that updates the database immediately. Show the system status with checkNativePushPermissions://, which sets nativePushEnabled, and link to settingsapp:// for users who want to switch off all notifications (Open App Settings docs).
Schedule cart or win-back reminders with sendlocalpushmsg:// only when marketing consent is true. When a user opts out, call sendlocalpushmsg://push.send.cancel; it cancels all scheduled local notifications, so reschedule the reminders the user asked for.
A minimal version for any web stack; the endpoint names are placeholders for your own backend. Built with Lovable? The Lovable push notification guide covers the provider setup around it.
// Notification screen after sign-up (Config.swift: askforpushpermissionatfirstrun = false)
var CONSENT_TEXT_V2 = "Send me offers and news by push notification. I can turn this off anytime in Settings.";
async function saveNotificationChoices(updates, offers) {
await fetch("/api/me/notification-prefs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
transactional: updates,
marketing: offers, // false unless the user switched it on
marketing_consent_text: offers ? CONSENT_TEXT_V2 : null,
marketing_consent_at: offers ? new Date().toISOString() : null
})
});
if (updates || offers) {
window.location.href = "registerpush://"; // iOS permission dialog, in context
}
}
// On later page loads: store the push ID once it exists (autoInjectVariable = true)
if (typeof onesignalplayerid !== "undefined" && onesignalplayerid) {
fetch("/api/me/push-id", { method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ provider: "onesignal", id: onesignalplayerid }) });
}
// Settings page: opt-out toggle
async function setOffers(enabled) {
await fetch("/api/me/notification-prefs", { method: "PATCH", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ marketing: enabled }) });
if (!enabled) {
window.location.href = "sendlocalpushmsg://push.send.cancel"; // clears ALL scheduled local reminders
}
}Describe the consent flow step by step and tell the reviewer exactly where the opt-out is.
Hello App Review team, Thank you for reviewing [App name] [version] ([build]). We changed how the app handles push notifications to comply with Guideline 4.5.4: 1. The app no longer asks for notification permission at launch, and every feature works when notifications are declined. 2. After sign-up, a notification screen offers two separate choices: "Order and account updates" and "Offers and news". The marketing option is off by default and shows this consent text: "[consent sentence]". 3. Only users who switch on "Offers and news" receive promotional notifications. Promotional local reminders are also sent only with this consent. 4. Users can opt out at any time in [Settings > Notifications > Offers and news]. The same screen links to the iOS notification settings. To verify: log in with the demo account from App Review Information and open [Settings > Notifications]. [New build: [number].] Best regards, [Name], [email]
askforpushpermissionatfirstrun is false; the permission dialog appears after the user has seen value.firebaseTopic is not used for promotions.No. The system dialog asks for permission to show notifications at all. Apple wants marketing consent in your own UI, with wording that says promotional messages will be sent, plus an opt-out inside the app.
Guideline 4.5.4 speaks of push notifications, but a promotional local notification looks the same to users and to reviewers. Treat cart and win-back reminders like marketing push and send them only with consent.
Send them only transactional messages until they opt in. Show the new notification screen once after the update, or add a short note in settings that explains the new "Offers and news" option.
The app must still work without them. Explain clearly what the user will miss, offer a link to the settings, and let them continue.
In the EU, marketing messages usually need consent under data protection and e-marketing rules too. The same opt-in screen, stored with a timestamp and the consent text, helps with both. If marketing is central to your business, ask a lawyer about your specific case.
Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
See plans on the main page$349 per license, one-time add-on
No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.
How the Cloud Builder works Try the free demo$698 per platform $798
Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.
Full Service details Powered byWinter Sale prices valid until December 31, 2026.
App Store & Google Play approval guarantee – or your money back within 14 days
Rather hand it over? Full Service: we configure, build and deliver within 72 hours, from $698 per platform. Questions? Chat with us 24/7.
Refunds are granted under the conditions listed in our FAQ: a non-content rejection by Apple and/or Google, claimed within 14 days after purchase.