Course outline

React Native / Inclusive native systems and release evidence / Lesson 16

Permissions, AppState, and session trust

Separate status reconciliation from user commands and preserve account ownership across interruption and permission changes.

About 4 min readContent reviewed
On this page

Lesson goals

  • A permission result is not an operation result
  • Request only in a comprehensible feature flow
  • Map statuses into explicit recovery choices

A permission result is not an operation result

An app can have permission while a device feature is unavailable or the operation still fails. Conversely, a denied feature can permit a useful fallback. Represent permission categories and capability outcomes separately instead of one success boolean. Platform setup, runtime authorization, and backend authorization are different boundaries. The first fragment uses Android’s permission API only after an explicit feature action and returns unsupported on other platforms. It does not grant iOS permission or create a cross-platform permission abstraction by itself. No permission request is executed in the authoring environment.

Request only in a comprehensible feature flow

The first module requests camera permission as an illustrative Android integration. The actual target must declare the appropriate native configuration and follow its current OS requirements. A user should understand why the feature needs access and what happens after denial. Do not call request in a render function or on every AppState activation. Reading status and requesting consent have different meanings. PermissionsAndroid exposes granted, denied, and never_ask_again results; preserve them rather than repeatedly prompting after a terminal denial. The fragment supplies no camera view, manifest edit, or actual device operation.

jsx Illustrative React Native module; requires the declared compatible application host.
import {Platform, PermissionsAndroid} from 'react-native';
export async function requestCameraForFeature() {
  if (Platform.OS !== 'android') return 'unsupported';
  return PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.CAMERA);
}
Expected output
A compatible Android host returns a documented permission status; other platforms return unsupported.

This native module fragment is unexecuted. Permission does not prove a camera session opened or that any image was captured.

Map statuses into explicit recovery choices

The second program maps synthetic status strings into application next steps. A denied result leads to explanation, while never_ask_again leads to a settings-oriented recovery rather than another automatic request. The exact screen wording and recovery mechanism depend on the actual platform and feature. Unknown categories remain unknown instead of being treated as granted. This pure policy can be tested under Node without system prompts. It does not validate the native permission API, current settings, or the success of the next capability operation. Keep those limitations with the model.

javascript Standalone JavaScript model with synthetic local inputs.
function permissionStep(status) {
  switch (status) {
    case 'granted': return 'perform-feature';
    case 'denied': return 'explain-denial';
    case 'never_ask_again': return 'offer-settings-recovery';
    case 'unsupported': return 'show-fallback';
    default: return 'unknown-status';
  }
}
console.log(permissionStep('never_ask_again'));
console.log(permissionStep('denied'));
console.log(permissionStep('future-value'));
Expected output
offer-settings-recovery
explain-denial
unknown-status

The policy never equates an unknown status with permission and performs no actual system request or settings navigation.

Resume reconciles state rather than replaying intent

An app returning active may have outdated permission, authentication, or cached availability. Refresh the relevant status through an owned operation, with duplicate-work and freshness rules. Do not automatically repeat a reservation or sensitive command merely because visibility changed. AppState is not a durable background scheduler or a guarantee that every final process event arrives before termination. Save valuable drafts under a deliberate policy. On logout, invalidate old publication rights and private caches; a still-mounted component can otherwise display a previous account’s delayed response after the next user enters.

Keep credentials and authoritative checks outside UI shortcuts

A hidden or disabled control is interaction feedback, not server access control. The authoritative service must validate current identity and permission when evaluating a command. Do not embed privileged backend secrets in bundles or build-time client variables, and do not log tokens or full private payloads to diagnose a permission issue. Test denial, settings changes, resume, logout during pending work, and a second session before old completion. Pure policy tests do not establish protected storage, native prompts, or device lifecycle. No real account, credential store, camera, or service is used here.

Common errors and fixes

Resume repeats the previous save

Why it happens
Visibility was treated as renewed user intent.
How to fix it
Reconcile status and require an explicit current command.
Prevent it next time
Repeat active transitions while a save is pending.

Unknown permission is treated as granted

Why it happens
Status categories were collapsed into a permissive default.
How to fix it
Preserve unknown and documented denial outcomes.
Prevent it next time
Include unsupported future values in policy checks.

A late response crosses account ownership

Why it happens
Request freshness omitted session identity.
How to fix it
Invalidate old work and compare session ownership before publication.
Prevent it next time
Log out and enter another session before a fake resolves.

Check your understanding

1. Does perform-feature mean the camera operation succeeded?

Show worked solution

No. It means the permission policy allows proceeding to the next step. The capability can still be unavailable or fail, and the application needs a separate result contract for that operation. A local status mapping cannot prove native registration or actual capture.

2. Why is a mounted flag insufficient after logout and login?

Show worked solution

The component can survive while the account entitled to its data changes. Compare session identity as well as request identity and scope caches accordingly. The same UI lifetime does not grant the next account access to the previous account’s pending result.

Key takeaways

  • A permission result is not an operation result
  • Keep credentials and authoritative checks outside UI shortcuts

Official references