FlutterFlow / flutterflow-issues

A community issue tracker for FlutterFlow.
131 stars 26 forks source link

"No permissions found in manifest for: []9" - permissions issue on Android 12 and older #2594

Open kashirin-dm opened 8 months ago

kashirin-dm commented 8 months ago

Has your issue been reported?

Current Behavior

To be able to upload photos to memory or Firebase, I request permission for the camera and gallery.

Everything works correctly on Android 13 and 14, and I see two popups requesting permissions.

On a new test blank project: On Android 12 and below, I only get one camera request but no second. On my working project created a couple of months ago: I don't get any requests at all on Android 12 and below.

Expected Behavior

On any version of Android, I should get two requests for permissions.

Steps to Reproduce

  1. Create an empty project.
  2. Add an additional permission "READ_MEDIA_IMAGES" to permissions (otherwise you won't get any requests on Android 13+)
  3. Create a button.
  4. Add a "Store media for upload" action.
  5. Add a request for Camera permission and condition for this permission.
  6. Add a request for Gallery permission and condition for this permission.
  7. Move the "Store media for upload" action to the end of the chain after requesting all permissions.
  8. Run the app in an emulator or on a physical device with Android below version 13.
  9. Click on the button and try to get all permissions.

Reproducible from Blank

Bug Report Code (Required)

IT4CiPHqw4tNrsNK1aqBbMB7/WAvKUR/RYIFjcB9TUkjHZPOD7AQP8nRP1dUcMfkYG9cfGeJhXwX/MqMiOzqUPEpCwWuR7pG+c91EQnwRn2gSr6bPJS3b0FQL9FTJ2qO0LSzrhNCNtNiLlEt7WaqNtiRUXPAO7X6C0cjBOaoXdeK2SrDX1iXc2URm05KZDPz

Context

I needed to add an additional READ_MEDIA_IMAGES permission because the permission request on Android 13+ just didn't work. (This should be added to the documentation or automatically added when loading media.)

I ran the tests on emulators running Android 14 and 11 and on real devices running Android 13, 12, and 9. On all devices below version 13, the problem is present.

If no permissions are requested, media uploads work correctly on any device. I didn't test permissions on Apple, as I'm making the app for Android only.

The contents of AndroidManifest:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>

On my two-month-old project on Android below version 13, permissions are not being requested at all, even in the emulator.

I tried updating permission_handler to version 11.3.0, but that didn't help. I've also tried removing READ_MEDIA_IMAGES manually from the manifest, which also did not affect older Android.

Visual documentation

Permissions:

image

Action Flow:

image

Android 11:

Screenshot 2024-03-26 143828

Android 14:

Screenshot 2024-03-26 145156

Screenshot 2024-03-26 145205

Additional Info

No response

Environment

- FlutterFlow version: v4.1
- Platform: Android 12, 11, 9
kashirin-dm commented 8 months ago

I've researched the problem, the source code of my project, and the code generated by FlutterFlow and concluded that the request always occurs for the photos permission. However, on older devices, a request for storage is needed. Therefore, it only works on newer versions of Android.

I wrote 2 custom actions to correct this behavior. They are not perfect and were done hastily, but they solve the problem.

I will share them here if they might be useful to someone.

The first action, "requestGalleryPermission", requests gallery access and does it differently depending on the Android version.

// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';

Future requestGalleryPermission() async {
  if (kIsWeb) {
    return;
  }
  if (Platform.isAndroid) {
    final androidInfo = await DeviceInfoPlugin().androidInfo;
    if (androidInfo.version.sdkInt <= 32) {
      return Permission.storage.request();
    }
  }
  return Permission.photos.request();
}

The second action, "checkGalleryPermission", checks the permission differently depending on the Android version.

// Automatic FlutterFlow imports
import '/backend/backend.dart';
import '/backend/schema/structs/index.dart';
import '/actions/actions.dart' as action_blocks;
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/actions/index.dart'; // Imports other custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom action code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!

import 'dart:io';
import 'package:permission_handler/permission_handler.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';

const kPermissionStateToBool = {
  PermissionStatus.granted: true,
  PermissionStatus.limited: true,
  PermissionStatus.denied: false,
  PermissionStatus.restricted: false,
  PermissionStatus.permanentlyDenied: false,
};

Future<bool> checkGalleryPermission() async {
  if (kIsWeb) {
    return true;
  }

  PermissionStatus status;
  if (Platform.isAndroid) {
    final androidInfo = await DeviceInfoPlugin().androidInfo;
    if (androidInfo.version.sdkInt <= 32) {
      status = await Permission.storage.status;
    } else {
      status = await Permission.photos.status;
    }
  } else {
    status = await Permission.photos.status;
  }

  return kPermissionStateToBool[status] ?? false;
}

You must set a Pubspec dependency in these two actions: device_info_plus: 9.1.0

Next, I create a chain in FF: the first action requests the gallery permission, and the second returns the permission status. Then, I check this status and perform my logic based on it.

ignalauret commented 8 months ago

Hey @kashirin-db thanks for your report. As you figured out, the permission handling has changed on Android 13. I'm glad you found out a solution for older versions and I thank you for sharing your solution to everyone that may encounter the same issue. I will elevate this to the engineering team to see if it can be implemented on the FlutterFlow side. Have a great day.

github-actions[bot] commented 7 months ago

This issue is stale because it has been open for 7 days with no activity. If there are no further updates, a team member will close the issue.