简体   繁体   English

Flutter 在启动时阻止对 iOS 的推送通知权限

[英]Flutter block push notification permission on iOS at startup

I'm deploying a flutter app and I ve a problem: when run it in iOS device I've a push notification request permission on a startup but I'd like to ask for permission in future screen.我正在部署一个 flutter 应用程序,我遇到了一个问题:在 iOS 设备中运行它时,我在启动时获得了推送通知请求权限,但我想在未来的屏幕上请求权限。 In detail I'd like to ask permission to the user in a dedicated page with a button:详细来说,我想在带有按钮的专用页面中向用户请求许可:

Future<NotificationSettings> checkPermissions() async {
    settings = await FirebaseMessaging.instance.requestPermission(
      announcement: true,
      carPlay: true,
      criticalAlert: true,
    );
    return settings;
  }
}

This is my main.dart这是我的主要。dart

import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';


Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  print('------- onBackgroundMessage ----------');
}

// ACTIVATE ANDROID NOTIFICATION IN FOREGROUND
const AndroidNotificationChannel channel = AndroidNotificationChannel(
  'high_importance_channel', // id
  'High Importance Notifications', // title
  'This channel is used for important notifications.', // description
  importance: Importance.high,
);

// ACTIVATE ANDROID NOTIFICATION IN FOREGROUND
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

//RemoteMessage globalMessage;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  // ACTIVATE ANDROID NOTIFICATION IN FOREGROUND
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);

  // ACTIVATE IOS NOTIFICATION IN FOREGROUND
  await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
    alert: true,
    badge: true,
    sound: true,
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: {
        '/': (context) => Application(),
        '/pushNotification': (context) => MessageScreen()
      },
    );
  }
}

class Application extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _Application();
}

class _Application extends State<Application> {
  var initializationSettings;
  var initializationSettingsAndroid;
  var initializationSettingsIOS;
  RemoteMessage foregroundMessage;

  @override
  void initState() {
    super.initState();

    print("_Application : inizio initState()");

    initializationSettingsAndroid =
        AndroidInitializationSettings('launch_background');
    initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: false,
      onDidReceiveLocalNotification: (id, title, body, payload) async {
        // your call back to the UI
      },
    );
    initializationSettings = InitializationSettings(
        android: initializationSettingsAndroid, iOS: initializationSettingsIOS);

    setOnNotificationClick(onNotificationClick);

    FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage message) {
      if (message != null) {
        //Navigator.push(context,
        //new MaterialPageRoute(builder: (context) => new LoginScreen()));
        Navigator.pushNamed(context, '/pushNotification',
            arguments: MessageArguments(message, true));
      }
    });

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;

      foregroundMessage = message;

      print('-------- onMessage ----------');

      //serve per notificare in android quando l'app è in foreground
      if (notification != null && android != null) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                // TODO add a proper drawable resource to android, for now using
                //      one that already exists in example app.
                icon: 'launch_background',
              ),
            ),
            payload: message.data.toString());
      }
    });

    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('---- onMessageOpenedApp ------------------');
      //Navigator.push(context,
      //  new MaterialPageRoute(builder: (context) => new LoginScreen()));
      Navigator.pushNamed(context, '/pushNotification',
          arguments: MessageArguments(message, true));
    });
  }

  setOnNotificationClick(Function onNotificationClick) async {
    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payload) async {
      onNotificationClick(payload);
    });
  }

  onNotificationClick(String payload) {
    print('---- onNotificationClick ------------------');
    print(payload);
    Navigator.pushNamed(context, '/pushNotification',
        arguments: MessageArguments(foregroundMessage, false));
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'XYZ',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      onGenerateRoute: RouteGenerator.generateRoute,
    );
  }
}

Do you have any ideas?你有什么想法?

thank you谢谢你

I've resolved in this way:我以这种方式解决了:

initializationSettingsIOS = IOSInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,

This is the sdk suggestion about initialize method:这是 sdk 关于初始化方法的建议:

/// Call this method on application before using the plugin further.
    ///
    /// Will return a [bool] value to indicate if initialization succeeded. On iOS this is dependent on if permissions have been granted to show
    /// notification When running in environment that is neither Android and iOS (e.g. when running tests), this will be a no-op and return true.
    ///
    /// Note that on iOS, initialisation may also request notification permissions where users will see a permissions prompt. This may be fine in
    /// cases where it's acceptable to do this when the application runs for the first time. However, if your application needs to do this at a
    /// later point in time, set the [IOSInitializationSettings.requestAlertPermission], [IOSInitializationSettings.requestBadgePermission] and
    /// [IOSInitializationSettings.requestSoundPermission] values to false. [IOSFlutterLocalNotificationsPlugin.requestPermissions] can then be
    /// called to request permissions when needed.



await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payload) async {
      onNotificationClick(payload);

We had the same problem, we found out that FlutterLocationNotificationsPlugin is the culprit.我们遇到了同样的问题,我们发现 FlutterLocationNotificationsPlugin 是罪魁祸首。 In our case, we didn't needed the Local Notifications Plugin anymore (we are using Firebase Remote Messages, and only used Local Notifications for test).在我们的例子中,我们不再需要本地通知插件(我们使用 Firebase 远程消息,并且只使用本地通知进行测试)。

So either: remove flutter_local_notifications from pubspec.yml or apply the patch like described by @masudani before using them.所以要么:从pubspec.yml中删除flutter_local_notifications ,或者在使用它们之前应用@masudani 描述的补丁。

Info on Flutter's Github issue: https://github.com/FirebaseExtended/flutterfire/issues/5897 Flutter 的 Github 问题信息: https://github.com/FirebaseExtended/flutterfire/issues/5897

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM