skip to Main Content

Previously I used the following code to ensure Firebase was initialised …

    typedef Callback = void Function(MethodCall call);

void setupFirebaseAuthMocks([Callback? customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  setupFirebaseCoreMocks();

  ///todo fix this
  MethodChannelFirebase.channel.setMockMethodCallHandler((call) async {
    if (call.method == 'Firebase#initializeCore') {
      return [
        {
          'name': defaultFirebaseAppName,
          'options': {
            'apiKey': '123',
            'appId': '123',
            'messagingSenderId': '123',
            'projectId': '123',
          },
          'pluginConstants': {},
        }
      ];
    }

    if (call.method == 'Firebase#initializeApp') {
      return {
        'name': call.arguments['appName'],
        'options': call.arguments['options'],
        'pluginConstants': {},
      };
    }

    if (customHandlers != null) {
      customHandlers(call);
    }

    return null;
  });
}

This no longer works since I updated to the latest version of firebase_core :

firebase_core: ^2.9.0
# firebase_core: ^1.3.0
cloud_firestore: ^4.5.0

The static analyser says the getter channel isn’t defined for the type MethodChannelFirebase … and my tests can’t run without:

setupFirebaseAuthMocks();

  setUpAll(() async {
    await Firebase.initializeApp();
  });

I also tried (as is the new requirement for firebase_core in the main application):

//setupFirebaseAuthMocks();

  setUpAll(() async {
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
  });

There doesn’t seem to be an obvious answer on here or in the docs… pointing me in the right direction would be greatly appreciated!

2

Answers


  1. Chosen as BEST ANSWER

    Posting my own answer in case anyone else benefits!

    The bottom line is you don't need to initialise App for a test anymore

    Firebase.initializeApp(); //not required

    Instead you must make sure that any time you call firebase in your app during a test that it has a suitable mock provided. If a suitable mock is provided then you can avoid the error message:

    [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

    An example of how to provide a mock is as follows

        import 'package:fake_cloud_firestore/fake_cloud_firestore.dart';
    
        final FakeFirebaseFirestore fakeFirebaseFirestoreManufacturersCollection = FakeFirebaseFirestore();
    
        initialiseFirestoreManufacturersCollectionFake() async {
      List<Manufacturer> testManufacturerList = [];
    
      testManufacturerList.add(Manufacturer(
          keyword: "none",
          id: "testManf1",
          countryOfOrigin: "United Kingdom",
          manufacturingLocations: [],
          distribution: [],
      ));
    
      testManufacturerList.forEach((manufacturer) async {
        await fakeFirebaseFirestoreManufacturersCollection
            .collection(FirestoreManufacturerUtils.manufacturersCollection)
            .doc(manufacturer.id)
            .set(manufacturer.toJson());
      });
    }
    
    main(){
    
      TestWidgetsFlutterBinding.ensureInitialized();
      
      
    
      setUpAll(() async {
        //await Firebase.initializeApp(); //no need for this anymore!
      });
    
    
      Widget testAppMultiTab({Widget? child}){
    
        ///before anything initialise the Firestore singleton with a Fake
        initialiseFirestoreManufacturersCollectionFake();
        var fakeFirebaseFirestoreManufacturersCollection = FirestoreFakerUtil.fakeFirebaseFirestoreManufacturersCollection;
        manufacturerInfo = ManufacturerInformation(firestore: fakeFirebaseFirestoreManufacturersCollection);
        
        return MaterialApp(
          home: Scaffold(
              body: ScopedModel<ManufacturerInformation>(model: manufacturerInfo,child: MaterialApp(
                            title: 'Manufacturing app',
                            home: HomeScreen(),
                          ),
                        ),
                      ),
                    ),
                  ))
          ),
        );
      }
    
      group("some tests which involve firestore calls", (){
      //...
      })
    }
    

    `

    Hopefully this will help someone out there!!


  2. Yes, there are some breaking changes in the firebase core platform interface api.

    You need to add following. It will work.

    import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
    import 'package:flutter/services.dart';
    import 'package:flutter_test/flutter_test.dart';
    
    void setupFirebaseAuthMocks([Callback? customHandlers]) {
      TestWidgetsFlutterBinding.ensureInitialized();
    
      setupFirebaseCoreMocks();
    }
    

    You can remove following method as channel is removed from latest dependency.

    MethodChannelFirebase.channel.setMockMethodCallHandler((call) async { 
    
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search