An app that asks for too much looks suspicious, to people and to store reviewers. So your app declares only what the plugins you turned on need. With no plugin turned on, it shows no permission prompt at all.
Android permissions
| Turned on | Permission added | Prompt shown? |
|---|---|---|
| Always | INTERNET | No |
| Location | ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION | Yes, the first time your site asks |
| Biometric unlock | USE_BIOMETRIC | No, the system window appears at use |
| Haptic feedback | VIBRATE | No |
| In-app subscriptions | com.android.vending.BILLING | No |
| Local notifications | POST_NOTIFICATIONS, RECEIVE_BOOT_COMPLETED | Yes on Android 13 and later, when your site calls requestPermission() |
| QR code scanner | None: the reader belongs to Google Play services | No |
| Document scanner | None: the scanner belongs to Google Play services | No |
| Contacts | None: people choose in the system's own contact picker | No |
| Calendar | None: the phone's calendar editor opens, people save the event | No |
iOS usage messages
On iOS, every sensitive feature has a message that explains why the app needs it. People see it in the system prompt, and App Review reads it.
| Turned on | Declared | When people see it |
|---|---|---|
| Biometric unlock | NSFaceIDUsageDescription | The first time Face ID is used |
| Location | NSLocationWhenInUseUsageDescription | The first time your site asks |
| QR code scanner | NSCameraUsageDescription | The first time your site calls scan() or requestPermission() |
| Document scanner | NSCameraUsageDescription (one message shared with the QR code scanner) | The first time your site calls scan() |
| Calendar | NSCalendarsUsageDescription | On iOS 15 and 16 only, the first time your site calls addEvent() |
Local notifications don't need a message: iOS shows its own prompt when your site calls requestPermission(). Contacts don't need one either: the contact picker runs outside your app and only returns what people choose.
Ask at the right moment
The system prompt appears when your site makes the call, and a refusal is hard to undo: people have to go to the phone's settings. So don't call it on the first page. Show why you need it first, then call it from a button.
// from a button such as "Find stores near me"
navigator.geolocation.getCurrentPosition(
(position) => showStores(position.coords),
(error) => showManualSearch(error), // refused or unavailable
);Declare what you collect
The stores ask you to describe the data your app handles, on Google Play in the Data safety form, on the App Store under App Privacy. Your site's own data collection counts, as does the Location plugin. Answer for your whole app, not only for what SaasToStore adds. After a build, your personal to-do list reminds you of what applies to your app.
Camera and microphone
A file input lets people take a photo or pick a file through the system's own picker, with no permission on your side. The QR code scanner and document scanner plugins use the camera only to read a code or capture a page: on Android through Google Play services, with no camera permission; on iOS with the camera message listed above. Live camera or microphone access from a page, such as a video call, isn't part of the plugin library today.