Flutterfire: [firebase_messaging] ERROR ITMS-90771: "Missing Info.plist value. The Info.plist key 'BGTaskSchedulerPermittedIdentifiers' must contain a list of identifiers used to submit and handle tasks when 'UIBackgroundModes' has a value of 'processing'

Created on 22 Dec 2019  路  6Comments  路  Source: FirebaseExtended/flutterfire

After I added firebase message to my flutter project and implemented it as described in the pub.dev readme, when I sent the app to the Apple App Store this error appeared right on uploading.

ERROR ITMS-90771: "Missing Info.plist value. The Info.plist key 'BGTaskSchedulerPermittedIdentifiers' must contain a list of identifiers used to submit and handle tasks when 'UIBackgroundModes' has a value of 'processing'. For more information, refer to the Information Property List Key Reference at https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Introduction/Introduction.html."

```console
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[鈭歖 Flutter (Channel stable, v1.12.13+hotfix.5, on Microsoft Windows [vers脙拢o 10.0.17763.914], locale pt-BR)

[!] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[鈭歖 Android Studio (version 3.5)
[!] IntelliJ IDEA Ultimate Edition (version 2018.3)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[!] IntelliJ IDEA Ultimate Edition (version 2019.1)
X Flutter plugin not installed; this adds Flutter specific functionality.
[鈭歖 VS Code (version 1.41.1)
[!] Connected device
! No devices available


### pubspec.yaml
```yaml
name: appsescverao
description: Aplicativo do Sesc Ver茫o Rio das Ostras

version: 3.0.0+3

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

  cupertino_icons: ^0.1.3
  http: ^0.12.0+2
  path_provider: ^1.5.1
  flutter_advanced_networkimage: ^0.6.2
  sqflite: ^1.2.0
  connectivity: ^0.4.6+1
  url_launcher: ^5.4.1
  cloud_firestore: ^0.13.0+1
  firebase_auth: ^0.15.2
  google_sign_in: ^4.1.0
  firebase_database: ^3.1.1
  rxdart: ^0.23.1
  webview_flutter: ^0.3.18+1
  auto_size_text: ^2.1.0
  flutter_map: ^0.8.0
  latlong: ^0.6.1
  queries: ^0.1.12
  firebase_analytics: ^5.0.9
  shared_preferences: ^0.5.6
  share: ^0.6.3+5
  map_launcher: ^0.3.2
  #audioplayers: ^0.13.5
  #audio_streams: ^1.0.0+2
  firebase_messaging: ^6.0.9
  #oktoast: ^2.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  intl_translation: ^0.17.7

flutter:

  uses-material-design: true

  assets:
    - assets/logo.png
    - assets/background.png
    - assets/background2.png
    - assets/background3.png
    - assets/user-avatar.png
    - assets/logo-pmro-cinza.png
    - assets/logo-pmro-branco.png
    - assets/wave-bottom.png
    - assets/wave-top.png
    - assets/logo2.png
    - assets/logo-branca.png

  fonts:
    - family: Big Noodle Titling
      fonts:
        - asset: fonts/big_noodle_titling.ttf
    - family: GlosaDisplayW01-Bold
      fonts:
        - asset: fonts/glosa_display_w01_bold.ttf
    - family: BakerieSmoothCondensedMedium
      fonts:
        - asset: fonts/BakerieSmoothCondensed-Medium.otf
    - family: BakerieSmoothBold
      fonts:
        - asset: fonts/BakerieSmooth-Bold.otf
    - family: iconsmind
      fonts:
        - asset: fonts/iconsmind.ttf

home_page.dart

import 'dart:io';
import 'dart:ui';
import 'package:flutter/material.dart';
import '../services/api_service.dart';
import '../style.dart';
import '../widgets/modal_progress_indicator.dart';
import 'menu.dart';
import 'package:flutter_advanced_networkimage/provider.dart';
import 'package:flutter_advanced_networkimage/transition.dart';
import 'package:flutter_advanced_networkimage/zoomable.dart';

import 'package:flutter/services.dart';

import 'package:firebase_messaging/firebase_messaging.dart';


class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return new HomePageState();
  }
}

class HomePageState extends State<HomePage> {
  BuildContext _ctx;
  final _scaffoldKey = new GlobalKey<ScaffoldState>();
  bool _loading = false;
  var apiRest = new ApiService();
  Size screenSize;
  var isPortrait = true;
  double widthTile = 120;
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
  String notificationMessage;
  bool isShowNotification = false;

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

  static Future<dynamic> myBackgroundMessageHandler(
      Map<String, dynamic> message) {
    /*if (message.containsKey('data')) {
      // Handle data message
      final dynamic data = message['data'];
      print("myBackgroundMessageHandler $data");
    }

    if (message.containsKey('notification')) {
      // Handle notification message
      final dynamic notification = message['notification'];
      print("myBackgroundMessageHandler $notification");
    }*/
    print("myBackgroundMessageHandler $message");
    // Or do other work.
  }

  initHomePageState() async {
    print("initHomePageState:");

    //Firebase Message Configura莽茫o

    _firebaseMessaging.autoInitEnabled().then((bool enabled) => print(enabled));
    _firebaseMessaging.setAutoInitEnabled(true).then((f) {
      _firebaseMessaging
          .autoInitEnabled()
          .then((bool enabled) => print(enabled));
    });
    _firebaseMessaging.configure(
      onMessage: (Map<String, dynamic> message) async {
        print("onMessage teste: $message");
        showNotification(message);
      },
      //onBackgroundMessage: Platform.isIOS ? myBackgroundMessageHandler : null,
      onLaunch: (Map<String, dynamic> message) async {
        print("onLaunch: $message");
      },
      onResume: (Map<String, dynamic> message) async {
        print("onResume: $message");
      },
    );
    //Future.delayed(Duration(seconds: 1), () {
    _firebaseMessaging.requestNotificationPermissions(IosNotificationSettings(
        sound: true, badge: true, alert: true, provisional: true));
    print("pedindo permisao");
    //});

    _firebaseMessaging.onIosSettingsRegistered
        .listen((IosNotificationSettings settings) {
      print("pediu permisao");
      print("Settings registered: $settings");
    });

    _firebaseMessaging.getToken().then((String token) {
      assert(token != null);
      setState(() {
        print("Push Messaging token: $token");
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    _ctx = context;
    final mediaQueryData = MediaQuery.of(context);
    isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
    screenSize = mediaQueryData.size;
    widthTile =
        isPortrait ? (screenSize.width / 2 - 20) : (screenSize.width / 3 - 20);

    return Scaffold(
      //appBar: AppBar(),
      key: _scaffoldKey,
      //backgroundColor: AppStyle.backgroundDark, //#3b4455
      body: Stack(
        children: _buildList(context),
      ),
      drawer: MenuPrincipal(),
    );
  }

  List<Widget> _buildList(BuildContext context) {
    var listview = SingleChildScrollView(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          //logo
          Container(
            width: double.infinity,
            height: screenSize.height / 3.7,
            child: Padding(
              padding: EdgeInsets.fromLTRB(0, 25, 0, 10),
              child: Image.asset('assets/logo.png'),
            ),
          ),
          //menu
          Container(
            width: screenSize.width,
            height: isPortrait ? 570 : 450,
            child: Stack(
              children: <Widget>[
                Positioned(
                  left: isPortrait
                      ? ((screenSize.width - widthTile * 2) / 2)
                      : ((screenSize.width - widthTile * 3) / 2),
                  top: 0,
                  child: Container(
                    width: isPortrait ? widthTile * 2 : widthTile * 3,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(10),
                      boxShadow: [
                        BoxShadow(
                            color: Color.fromRGBO(128, 251, 255, 0.52),
                            blurRadius: 10),
                      ],
                    ),
                    height:
                        isPortrait ? 500 : 800, //vertival=360 horizontal=240,
                    child: ClipRRect(
                      borderRadius: BorderRadius.all(Radius.circular(10)),
                      child: Container(
                        //padding: EdgeInsets.all(10),
                        color: Colors.white,
                        child: Wrap(
                          children: <Widget>[
                            tile(
                                route: "/agendas",
                                title: "PROGRAMA脟脙O",
                                iconUnicode: "\uEB0C"),
                            tile(
                                route: "/atracoes",
                                title: "ARTISTAS",
                                iconUnicode: "\uE851"),
                            tile(
                                route: "/hospedagem",
                                title: "ONDE FICAR",
                                iconUnicode: "\uE6FA"),
                            tile(
                                route: "/alimentacao",
                                title: "ONDE COMER",
                                iconUnicode: "\uEB84"),
                            tile(
                                route: "/noticia",
                                title: "NOT脥CIAS",
                                iconUnicode: "\ueafe"),
                            tile(
                                route: "/live",
                                title: "LIVE",
                                iconUnicode: "\uedd1"),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),

                //wave
                Positioned(
                  bottom: 0,
                  child: Container(
                    //color: Colors.red,
                    width: screenSize.width,
                    //color: Colors.amberAccent,
                    height: 220,
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
                      child: Image.asset(
                        'assets/wave-bottom.png',
                        fit: BoxFit.fill,
                      ),
                    ),
                  ),
                ),

                //logo
                Positioned(
                  left: isPortrait
                      ? (screenSize.width - screenSize.width / 2) / 2
                      : (screenSize.width - screenSize.width / 3) / 2,
                  bottom: 30,
                  child: Container(
                    width: isPortrait
                        ? screenSize.width / 2
                        : screenSize.width / 3,
                    child: Padding(
                      padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
                      child: Image.asset(
                        'assets/logo-pmro-branco.png',
                        fit: BoxFit.fitHeight,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          )

          //
        ],
      ),
    );

    var l = new List<Widget>();

    //background page
    l.add(
      Container(
        width: double.infinity,
        height: double.infinity,
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('assets/background.png'),
            fit: BoxFit.cover,
          ),
        ),
      ),
    );

    l.add(listview);

    //bot茫o menu
    l.add(Positioned(
        left: 10,
        top: 25,
        child: Container(
          decoration: BoxDecoration(
            color: Color(0xAA26B4D6), //Colors.lightBlue[100]
            shape: BoxShape.circle,
          ),
          child: IconButton(
            icon: Icon(
              Icons.menu,
              color: Colors.white,
            ),
            onPressed: () => _scaffoldKey.currentState.openDrawer(),
          ),
        )));

    if (_loading) {
      l.add(modalProgressIndicator());
    }

    if (isShowNotification) {
      l.add(notificationDialog());
    }
    return l;
  }

  showNotification(Map<String, dynamic> message) {
    if (message != null) {
      if (message.containsKey('notification')) {
        var not = message['notification'];
        if (not != null) {
          if (not.containsKey('body')) {
            notificationMessage = not['body'];
          }
        }
      }
    }
    if (notificationMessage != null) {
      setState(() {
        isShowNotification = true;
      });
      Future.delayed(Duration(seconds: 8), () {
        setState(() {
          isShowNotification = false;
        });
      });
    }
  }

  notificationDialog() {
    return Positioned(
      left: 0,
      right: 0,
      bottom: 0,
      child: Container(
          color: Color.fromRGBO(20, 20, 20, 0.5),
          child: Padding(
            padding: EdgeInsets.fromLTRB(16, 10, 16, 10),
            child: Text(
              notificationMessage,
              style: TextStyle(color: Colors.white),
            ),
          )),
    );
  }

  tile(
      {Function onTap,
      String title,
      String route,
      String iconUnicode = "\uEB0C"}) {
    return InkWell(
      onTap: onTap != null
          ? onTap
          : () {
              if (route != null) {
                Navigator.of(context).pushNamed(route);
              }
            },
      child: Container(
        width: widthTile,
        height: 120,
        decoration: BoxDecoration(
          border:
              Border.all(color: Color.fromRGBO(15, 60, 225, 0.11), width: 0.5),
        ),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Padding(
              padding: EdgeInsets.fromLTRB(5, 10, 5, 10),
              child: Stack(
                children: <Widget>[
                  Text(
                    iconUnicode,
                    style: TextStyle(
                      fontSize: 40,
                      fontFamily: "iconsmind",
                      color: Color(0xFF26B4D6),
                    ),
                  )
                ],
              ),
            ),
            Text(
              title,
              style: TextStyle(
                  fontSize: 15,
                  fontFamily: 'Roboto',
                  color: Color(0xFF26B4D6),
                  fontWeight: FontWeight.bold),
            ),
          ],
        ),
      ),
    );
  }
}

crowd messaging bug

Most helpful comment

@tyegah, The error is ERROR ITMS-90771: "Missing Info.plist value. The Info.plist key 'BGTaskSchedulerPermittedIdentifiers' must contain a list of identifiers used to submit and handle tasks when 'UIBackgroundModes' has a value of 'processing'. For more information....."

So you put this information to [YOUR_PROJECT_DIR]/ios/Runner/Info.plist

The value com.your-domain.app is your PRODUCT_BUNDLE_IDENTIFIER

Example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>com.your-domain.app</string>
    </array>
</dict>
</plist>

All 6 comments

Hi @insinfo, I added a value like this and app runner validate success. I don't know root cause and maybe it will make a bug.

<plist version="1.0">
<dict>
    <key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>com.your-domain.app</string>
    </array>
</dict>
</plist>

@kimthangatm Hi, where did you put that plist file/value? I am experiencing the same thing

@tyegah, The error is ERROR ITMS-90771: "Missing Info.plist value. The Info.plist key 'BGTaskSchedulerPermittedIdentifiers' must contain a list of identifiers used to submit and handle tasks when 'UIBackgroundModes' has a value of 'processing'. For more information....."

So you put this information to [YOUR_PROJECT_DIR]/ios/Runner/Info.plist

The value com.your-domain.app is your PRODUCT_BUNDLE_IDENTIFIER

Example:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>com.your-domain.app</string>
    </array>
</dict>
</plist>

@kimthangatm solution also works for my case, thks!

Sorry for barging in, but the firebase messaging installation instructions doesn't state that one needs to add "Background processing" to the background modes, or am I missing out something?

Sorry for barging in, but the firebase messaging installation instructions doesn't state that one needs to add "Background processing" to the background modes, or am I missing out something?

Correct, this isn't something messaging uses or even recommends setting up - so this is not related to FlutterFire

Was this page helpful?
0 / 5 - 0 ratings