flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [firebase_app_check] `.getToken()` is not working for iOS and macOS

Open nilsreichardt opened this issue 2 years ago • 3 comments

Bug report

Describe the bug Running await FirebaseAppCheck.instance.getToken() throws Unhandled Exception: [firebase_app_check/unknown] The operation couldn’t be completed. (com.firebase.appCheck error 0.) when running this line on iOS and macOS.

Steps to reproduce

Steps to reproduce the behavior:

  1. Copy the code from "Sample project".
  2. Run it on iOS or macOS.
  3. Press the button

Expected behavior

Should return the token with exceptions.

Sample project

Reproducible example
import 'dart:developer';

import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  await FirebaseAppCheck.instance.activate();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('App Check Issue'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            final token = await FirebaseAppCheck.instance.getToken();
            if (token != null) {
              log(token);
            }
          },
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      return web;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        return android;
      case TargetPlatform.iOS:
        return ios;
      case TargetPlatform.macOS:
        return macos;
      default:
        throw UnsupportedError(
          'DefaultFirebaseOptions are not supported for this platform.',
        );
    }
  }

  static const FirebaseOptions web = FirebaseOptions(
    apiKey: 'AIzaSyB7wZb2tO1-Fs6GbDADUSTs2Qs3w08Hovw',
    appId: '1:406099696497:web:87e25e51afe982cd3574d0',
    messagingSenderId: '406099696497',
    projectId: 'flutterfire-e2e-tests',
    authDomain: 'flutterfire-e2e-tests.firebaseapp.com',
    databaseURL:
        'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
    storageBucket: 'flutterfire-e2e-tests.appspot.com',
    measurementId: 'G-JN95N1JV2E',
  );

  static const FirebaseOptions android = FirebaseOptions(
    apiKey: 'AIzaSyCdRjCVZlhrq72RuEklEyyxYlBRCYhI2Sw',
    appId: '1:406099696497:android:0d4ed619c031c0ac3574d0',
    messagingSenderId: '406099696497',
    projectId: 'flutterfire-e2e-tests',
    databaseURL:
        'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
    storageBucket: 'flutterfire-e2e-tests.appspot.com',
  );

  static const FirebaseOptions ios = FirebaseOptions(
    apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
    appId: '1:406099696497:ios:acd9c8e17b5e620e3574d0',
    messagingSenderId: '406099696497',
    projectId: 'flutterfire-e2e-tests',
    databaseURL:
        'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
    storageBucket: 'flutterfire-e2e-tests.appspot.com',
    androidClientId:
        '406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com',
    iosClientId:
        '406099696497-taeapvle10rf355ljcvq5dt134mkghmp.apps.googleusercontent.com',
    iosBundleId: 'io.flutter.plugins.firebase.tests',
  );

  static const FirebaseOptions macos = FirebaseOptions(
    apiKey: 'AIzaSyDooSUGSf63Ghq02_iIhtnmwMDs4HlWS6c',
    appId: '1:406099696497:ios:acd9c8e17b5e620e3574d0',
    messagingSenderId: '406099696497',
    projectId: 'flutterfire-e2e-tests',
    databaseURL:
        'https://flutterfire-e2e-tests-default-rtdb.europe-west1.firebasedatabase.app',
    storageBucket: 'flutterfire-e2e-tests.appspot.com',
    androidClientId:
        '406099696497-tvtvuiqogct1gs1s6lh114jeps7hpjm5.apps.googleusercontent.com',
    iosClientId:
        '406099696497-taeapvle10rf355ljcvq5dt134mkghmp.apps.googleusercontent.com',
    iosBundleId: 'io.flutter.plugins.firebase.tests',
  );
}

Additional context

[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: [firebase_app_check/unknown] The operation couldn’t be completed. (com.firebase.appCheck error 0.)

#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607:7)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167:18)
<asynchronous suspension>
#2      MethodChannel.invokeMapMethod (package:flutter/src/services/platform_channel.dart:367:43)
<asynchronous suspension>
#3      MethodChannelFirebaseAppCheck.getToken (package:firebase_app_check_platform_interface/src/method_channel/method_channel_firebase_app_check.dart:85:22)
<asynchronous suspension>
#4      MyApp.build.<anonymous closure> (package:tests/main.dart:28:27)
<asynchronous suspension>

#0      MethodChannelFirebaseAppCheck.getToken (package:firebase_app_check_platform_interface/src/method_channel/method_channel_firebase_app_check.dart:92:7)
<asynchronous suspension>
#1      MyApp.build.<anonymous closure> (pac<…>

Flutter doctor

Run flutter --version and paste the output below:

Click To Expand
Flutter 3.0.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision cd41fdd495 (3 weeks ago) • 2022-06-08 09:52:13 -0700
Engine • revision f15f824b57
Tools • Dart 2.17.3 • DevTools 2.12.2

Flutter dependencies

Using firebase_app_check 0.0.6+14


nilsreichardt avatar Jun 26 '22 23:06 nilsreichardt

Thanks for the report. Using code sample above, I am getting same error as reported.

darshankawar avatar Jun 27 '22 12:06 darshankawar

Any update on this?

MerryOscar avatar Jun 30 '22 11:06 MerryOscar

Hey @nilsreichardt, I've just spent a while figuring out how to get this working again. I've updated the example app so it works but not sure if this will run out the box for other users as I had to paste the debug token generated on app start into the Firebase console.

Here are the steps I took:

  1. Add this snippet of code to the AppDelegate.
  2. Add this argument -FIRDebugEnabled to the Runner's debug schema in "Arguments Passed On Launch": Screenshot 2022-08-02 at 13 56 38

Once the above is configured (and you have already setup your app with Firebase using flutterfire configure), you can run the app and a debug token is printed in the console by the iOS Firebase SDK. You need to paste in your Firebase console for the relevant app in "Manage debug tokens":

Screenshot 2022-08-02 at 14 04 55

Once all this setup is complete, you will no longer receive this error.

Hey @kevinthecheung, is there any chance we could have an example of how to setup the FIRAppCheckDebugProviderFactory for iOS Firebase App Check for Flutter?

Currently, the docs point to the iOS debug setup here.

Which takes you to the iOS debug page which has this code snippet for iOS:

Screenshot 2022-08-02 at 14 15 12

But Flutter developers need to update their AppDelegate.m like this:

#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
@import Firebase;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
#if DEBUG
  FIRAppCheckDebugProviderFactory *providerFactory = [[FIRAppCheckDebugProviderFactory alloc] init];
  [FIRAppCheck setAppCheckProviderFactory:providerFactory];
#endif
  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

russellwheatley avatar Aug 02 '22 13:08 russellwheatley