Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running Test throws MissingPluginException(No implementation found for method Firebase#initializeCore on channel plugins.flutter.io/firebase_core #3311

Closed
oakstair opened this issue Aug 24, 2020 · 32 comments
Labels
plugin: core type: bug Something isn't working

Comments

@oakstair
Copy link

oakstair commented Aug 24, 2020

Failing to write simple unit test using firebase emulators
Yesterday I upgrade to latest and greatest firebase/firestore plugins and decided to try out the firebase emulators to add some testing of my data access objects.

I fail to get the test up and running agains the emulators due to the error below

I saw some other issues that has been closed regarding the same error but with no solution that suited me.

I guess this is a simple mistake form my side in the code when connecting to the emulators.

MissingPluginException(No implementation found for method Firebase#initializeCore on channel plugins.flutter.io/firebase_core)

My test code

/// TODO: Get firebase emulators to work an use them for unit testing dao's
void main() {

  TournamentDao dao;

  setUpAll(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
    FirebaseFirestore.instance.settings = Settings(host: 'localhost:8080', sslEnabled: false, persistenceEnabled: false);

    GetIt.I.registerSingleton<TournamentDao>(TournamentDaoImpl());
  });

  setUp(() {
    dao = GetIt.I<TournamentDao>();
  });

  test("TournamentDao.crud", () async {
   
    Tournament t = Tournament();
    t.name = 'Tezt';
    dao.create(t);

    var list = await dao.list(10);
    expect(list.length, 1);
  });

Firebase versions

  cloud_firestore: ^0.14.0
  firebase_auth: 0.18.0
  firebase_core: ^0.5.0
  firebase: ^7.3.0

Firebase emulators startup

firebase emulators:start
i  emulators: Starting emulators: functions, firestore, database, hosting
⚠  functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: pubsub
⚠  Your requested "node" version "10" doesn't match your global version "12"
i  firestore: Firestore Emulator logging to firestore-debug.log
i  database: Database Emulator logging to database-debug.log
i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "/Users/gunnar/git/dart/chess-champion/functions" for Cloud Functions...

┌───────────────────────────────────────────────────────────────────────┐
│ ✔  All emulators ready! View status and logs at http://localhost:4000 │
└───────────────────────────────────────────────────────────────────────┘

┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator  │ Host:Port      │ View in Emulator UI             │
├───────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├───────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:8080 │ http://localhost:4000/firestore │
├───────────┼────────────────┼─────────────────────────────────┤
│ Database  │ localhost:9000 │ http://localhost:4000/database  │
├───────────┼────────────────┼─────────────────────────────────┤
│ Hosting   │ localhost:5000 │ n/a                             │
└───────────┴────────────────┴─────────────────────────────────┘
  Other reserved ports: 4400, 4500

Issues? Report them at https://github.com/firebase/firebase-tools/issues and attach the *-debug.log files.

Flutter doctor
Run flutter doctor and paste the output below:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.20.2, on Mac OS X 10.15.6 19G73, locale sv-SE)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.6)
[✓] Android Studio (version 4.0)
[✓] IntelliJ IDEA Ultimate Edition (version 2020.2)
[✓] Connected device (1 available)

• No issues found!
@Ehesp
Copy link
Member

Ehesp commented Aug 24, 2020

The error "MissingPluginException(No implementation found for method Firebase#initializeCore on channel plugins.flutter.io/firebase_core)" points towards your Dart code being updated, but your native code hasn't updated.

Can you try running flutter clean and rebuilding?

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020 via email

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020

I saw some comment about using localhost but have tried 0.0.0.0 or my ip with same result.

@Ehesp
Copy link
Member

Ehesp commented Aug 24, 2020

The emulator vs the error message have no relevance - try wiping all the caches, uninstalling the app etc, something is being cached.

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020 via email

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020

Even if there is no relevance it is thrown when calling Firebase.initializeApp

Skärmavbild 2020-08-24 kl  18 17 44

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020

Ok I get it now that this has nothing to do with pointing firebase to the emulator. I get the same error also when removing the line that configs towards the emulator.

It must be something that differs when running my tests and when running my flutter app that causes this.

@oakstair
Copy link
Author

oakstair commented Aug 24, 2020

My full test class attempt looks like this.

import 'package:chess_champion/model/dao/tournament_dao.dart';
import 'package:chess_champion/model/entity/tournament.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart';
import 'package:get_it/get_it.dart';
import 'package:test/test.dart';

/// TODO: Get firebase emulators to work and use them for unit testing dao's
void main() {

  TournamentDao dao;

  setUpAll(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
    // 192.168.0.31
    // FirebaseFirestore.instance.settings = Settings(host: '0.0.0.0:8080', sslEnabled: false, persistenceEnabled: true);

    GetIt.I.registerSingleton<TournamentDao>(TournamentDaoImpl());
  });

  setUp(() {
    dao = GetIt.I<TournamentDao>();
  });

  test("TournamentDao.crud", () async {
    Tournament t = Tournament();
    t.name = 'Tezt';
    dao.create(t);

    var list = await dao.list(10);
    expect(list.length, 1);
  });

}


@eriklange
Copy link

I have the same issue. It works fine when I initialize the app in my actual app, but the same MissingPluginException gets thrown when I attempt the same thing in one of my simple tests.

@TahaTesser
Copy link

Hi @oakstair
Can you please provide a flutter test --verbose logs, and a minimal complete reproducible code sample without using third party packages
Thank you

@TahaTesser TahaTesser added the blocked: customer-response Waiting for customer response, e.g. more information was requested. label Aug 26, 2020
@google-oss-bot
Copy link

Hey @oakstair. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 7 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

@google-oss-bot google-oss-bot added the Stale Issue with no recent activity label Sep 4, 2020
@oakstair
Copy link
Author

oakstair commented Sep 4, 2020

I will try to get some time today to do a mini project that reproduces this.

@eriklange You don’t have a mini project?

@google-oss-bot google-oss-bot added Needs Attention This issue needs maintainer attention. and removed blocked: customer-response Waiting for customer response, e.g. more information was requested. Stale Issue with no recent activity labels Sep 4, 2020
@oakstair
Copy link
Author

oakstair commented Sep 4, 2020

Here is a minproject thar reproduces the bug

https://bitbucket.org/oakstair/firestore_missing_plugin_bug/src/master/

@TahaTesser TahaTesser removed the Needs Attention This issue needs maintainer attention. label Sep 4, 2020
@TahaTesser
Copy link

logs
[ +242 ms] test 0: starting test
/Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example/test/user_dao_test.dart
[  +16 ms] test 0: starting shell process
[   +8 ms] Stopping scan for flutter_test_config.dart; found project root at
/Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example
[   +6 ms] Compiler will use the following file as its incremental dill file:
/var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_compiler.eZLb10/output.dill
[        ] Listening to compiler controller...
[   +7 ms] Compiling
file:///var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_listener.NCG87j/listener.dart
[  +12 ms] /Users/tahatesser/Code/flutter_dev/bin/cache/dart-sdk/bin/dart --disable-dart-dev
/Users/tahatesser/Code/flutter_dev/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot --sdk-root
/Users/tahatesser/Code/flutter_dev/bin/cache/artifacts/engine/common/flutter_patched_sdk/ --incremental --target=flutter
--debugger-module-names --experimental-emit-debug-metadata -Ddart.developer.causal_async_stacks=true --output-dill
/var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_compiler.eZLb10/output.dill --packages
/Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example/.packages -Ddart.vm.profile=false
-Ddart.vm.product=false
--bytecode-options=source-positions,local-var-info,debugger-stops,instance-field-initializers,keep-unreachable-code,avoid-cl
osure-call-instructions --enable-asserts --track-widget-creation --initialize-from-dill
/Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example/build/testfile.dill.track.dill
[  +30 ms] <- compile
file:///var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_listener.NCG87j/listener.dart
[+1077 ms] <- accept
[        ] <- reset
[        ] Compiling
/var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_listener.NCG87j/listener.dart took 1120ms
[   +1 ms] /Users/tahatesser/Code/flutter_dev/bin/cache/artifacts/engine/darwin-x64/flutter_tester --disable-observatory
--enable-checked-mode --verify-entry-points --enable-software-rendering --skia-deterministic-rendering
--enable-dart-profiling --non-interactive --use-test-fonts
--packages=/Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example/.packages
/var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_listener.NCG87j/listener.dart.dill
[   +1 ms] Using this directory for fonts configuration:
/var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_fonts.0NNQl7
[   +7 ms] test 0: awaiting initial result for pid 14109
[ +336 ms] test 0: process with pid 14109 connected to test harness
[   +1 ms] test 0: awaiting test result for pid 14109
00:01 +0 -2: /Users/tahatesser/AndroidStudioProjects/triage/flutterfire_examples/firebase_auth_example/test/user_dao_test.dart: (setUpAll) [E]
  MissingPluginException(No implementation found for method Firebase#initializeCore on channel plugins.flutter.io/firebase_core)
  package:flutter/src/services/platform_channel.dart 157:7  MethodChannel._invokeMethod
  
00:01 +0 -2: ... (tearDownAll)                                                                                             [ +225 ms] test 0: process with pid 14109 no longer needed by test harness
[        ] test 0: cleaning up...
[        ] test 0: ensuring end-of-process for shell
[  +10 ms] test 0: deleting temporary directory
[   +3 ms] test 0: shutting down test harness socket server
[   +2 ms] test 0: finished
00:01 +0 -2: Some tests failed.                                                                                            
[  +11 ms] Deleting /var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_compiler.eZLb10...
[   +3 ms] killing pid 14101
[  +35 ms] Deleting /var/folders/7t/qr_jg4155x53wn0m3nmqb8g80000gn/T/flutter_tools.pziWSp/flutter_test_fonts.0NNQl7...
[   +5 ms] test package returned with exit code 1
[  +10 ms] "flutter test" took 3,057ms.
[   +6 ms] 
           #0      throwToolExit (package:flutter_tools/src/base/common.dart:14:3)
           #1      TestCommand.runCommand (package:flutter_tools/src/commands/test.dart:282:7)
           <asynchronous suspension>
           #2      FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:912:18)
           #3      _rootRunUnary (dart:async/zone.dart:1198:47)
           #4      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
           #5      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
           #6      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
           #7      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
           #8      Future._completeWithValue (dart:async/future_impl.dart:529:5)
           #9      Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
           #10     _rootRun (dart:async/zone.dart:1190:13)
           #11     _CustomZone.run (dart:async/zone.dart:1093:19)
           #12     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
           #13     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
           #14     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
           #15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
           #16     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13)
           #17     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:169:5)
           
           
[ +164 ms] ensureAnalyticsSent: 160ms
[   +2 ms] Running shutdown hooks
[        ] Shutdown hook priority 4
[   +1 ms] Shutdown hooks complete
[        ] exiting with code 1
flutter doctor -v
[✓] Flutter (Channel dev, 1.22.0-9.0.pre, on Mac OS X 10.15.6 19G2021, locale
    en-GB)
    • Flutter version 1.22.0-9.0.pre at /Users/tahatesser/Code/flutter_dev
    • Framework revision 7a43175198 (6 days ago), 2020-08-28 23:18:04 -0400
    • Engine revision 07e2520d5d
    • Dart version 2.10.0 (build 2.10.0-73.0.dev)

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/tahatesser/Code/sdk
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = /Users/tahatesser/Code/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.7)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.7, Build version 11E801a
    • CocoaPods version 1.9.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 48.1.2
    • Dart plugin version 193.7547
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)

[✓] VS Code (version 1.48.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.14.0

[✓] Connected device (4 available)
    • iPhone 11 (mobile) • EDB19945-0B9F-4A6E-BAA1-425E68E3B6D6 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-13-7 (simulator)
    • macOS (desktop)    • macos                                • darwin-x64
      • Mac OS X 10.15.6 19G2021
    • Web Server (web)   • web-server                           • web-javascript
      • Flutter Tools
    • Chrome (web)       • chrome                               • web-javascript
      • Google Chrome 85.0.4183.83

• No issues found!

@TahaTesser TahaTesser changed the title Firebase Emulators and simple Flutter test gives MissingPluginException Running Test throws MissingPluginException(No implementation found for method Firebase#initializeCore on channel plugins.flutter.io/firebase_core Sep 4, 2020
@TahaTesser TahaTesser added plugin: core type: bug Something isn't working labels Sep 4, 2020
@eriklange
Copy link

@oakstair I had a few 3rd party packages in my project. Thank you for making the miniproject!

@oakstair
Copy link
Author

oakstair commented Sep 4, 2020

@oakstair I had a few 3rd party packages in my project. Thank you for making the miniproject!

No problem! When I studied (long time age) I didn't even have any time for studying :-)

@eriklange
Copy link

@oakstair I had a few 3rd party packages in my project. Thank you for making the miniproject!

No problem! When I studied (long time age) I didn't even have any time for studying :-)

That's understandable! App development is a hobby of mine, so I enjoy every moment of it, especially with Flutter :)

@Parakoos
Copy link

So... Has anyone managed to run unit tests with FlutterFire ever? I'm getting the same issue and I don't even know if it is meant to work during unit testing or if I should give up the idea of testing...

@10ndavis
Copy link

I am also facing this issue. Everything runs fine except in testing.

@dylan-sharp
Copy link

dylan-sharp commented Nov 3, 2020

So I faced a similar issue in testing. I was attempting to create Document References during testing and calling await Firebase.initializeApp(); inside my setUpAll()

In my case I solved this by pulling the following file into my test directory which hooks into mock call handlers to be used throughout the test: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/test/mock.dart

For reference to contents of file:

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

typedef Callback(MethodCall call);

setupCloudFirestoreMocks([Callback customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  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;
  });
}

Then in each test I would do the following:

void main() {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
  });

// ALL MY TESTS WOULD BE HERE

}

@takeru
Copy link

takeru commented Nov 9, 2020

I think the flutter test is running on neither iOS nor Android, so what if we're talking about running it in a macos environment?

https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/pubspec.yaml#L16

flutter testのときはiOSでもAndroidでもない環境で動いていると思います。macosの環境で動かすということにしたらどうでしょうか?

@yulkin2002
Copy link

So I faced a similar issue in testing. I was attempting to create Document References during testing and calling await Firebase.initializeApp(); inside my setUpAll()

In my case I solved this by pulling the following file into my test directory which hooks into mock call handlers to be used throughout the test: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/test/mock.dart

For reference to contents of file:

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

typedef Callback(MethodCall call);

setupCloudFirestoreMocks([Callback customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  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;
  });
}

Then in each test I would do the following:

void main() {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
  });

// ALL MY TESTS WOULD BE HERE

}

thank you for sharing, this fixed the error for me

@fer-ri
Copy link

fer-ri commented Feb 7, 2021

So I faced a similar issue in testing. I was attempting to create Document References during testing and calling await Firebase.initializeApp(); inside my setUpAll()

In my case I solved this by pulling the following file into my test directory which hooks into mock call handlers to be used throughout the test: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/test/mock.dart

For reference to contents of file:

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

typedef Callback(MethodCall call);

setupCloudFirestoreMocks([Callback customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  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;
  });
}

Then in each test I would do the following:

void main() {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
  });

// ALL MY TESTS WOULD BE HERE

}

Not works for me

package:cloud_firestore_platform_interface/src/method_channel/utils/exception.dart 13:5                     convertPlatformException
package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart 80:13  MethodChannelDocumentReference.get

MissingPluginException(No implementation found for method DocumentReference#get on channel plugins.flutter.io/firebase_firestore)

My test file

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'cloud_firestore_mock.dart';

void main() async {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();

    FirebaseFirestore.instance.settings = Settings(
      sslEnabled: false,
      host: '192.168.100.9:8080',
    );
  });

  test('Connect to emulator', () async {
    FirebaseFirestore firestore = FirebaseFirestore.instance;

    var doc = await firestore.doc('users/user-a').get();

    print(doc.data());
  });
}

Command to run

flutter test  --plain-name "Connect to emulator" test/unit_test.dart

Firebase packages

  firebase_core: ^0.7.0
  firebase_auth: ^0.20.0+1
  cloud_functions: ^0.9.0
  cloud_firestore: ^0.16.0

Thanks

@uris77
Copy link

uris77 commented Mar 26, 2021

The mocking method does not work for me either, because we have to also mock Query#get. But I don't want to do that when using an emulator. How do folks even write integration tests for firebase?

@dylan-sharp
Copy link

So I faced a similar issue in testing. I was attempting to create Document References during testing and calling await Firebase.initializeApp(); inside my setUpAll()
In my case I solved this by pulling the following file into my test directory which hooks into mock call handlers to be used throughout the test: https://github.com/FirebaseExtended/flutterfire/blob/master/packages/cloud_firestore/cloud_firestore/test/mock.dart
For reference to contents of file:

// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:firebase_core_platform_interface/firebase_core_platform_interface.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

typedef Callback(MethodCall call);

setupCloudFirestoreMocks([Callback customHandlers]) {
  TestWidgetsFlutterBinding.ensureInitialized();

  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;
  });
}

Then in each test I would do the following:

void main() {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();
  });

// ALL MY TESTS WOULD BE HERE

}

Not works for me

package:cloud_firestore_platform_interface/src/method_channel/utils/exception.dart 13:5                     convertPlatformException
package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart 80:13  MethodChannelDocumentReference.get

MissingPluginException(No implementation found for method DocumentReference#get on channel plugins.flutter.io/firebase_firestore)

My test file

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'cloud_firestore_mock.dart';

void main() async {
  setupCloudFirestoreMocks();

  setUpAll(() async {
    WidgetsFlutterBinding.ensureInitialized();

    await Firebase.initializeApp();

    FirebaseFirestore.instance.settings = Settings(
      sslEnabled: false,
      host: '192.168.100.9:8080',
    );
  });

  test('Connect to emulator', () async {
    FirebaseFirestore firestore = FirebaseFirestore.instance;

    var doc = await firestore.doc('users/user-a').get();

    print(doc.data());
  });
}

Command to run

flutter test  --plain-name "Connect to emulator" test/unit_test.dart

Firebase packages

  firebase_core: ^0.7.0
  firebase_auth: ^0.20.0+1
  cloud_functions: ^0.9.0
  cloud_firestore: ^0.16.0

Thanks

The mocking method does not work for me either, because we have to also mock Query#get. But I don't want to do that when using an emulator. How do folks even write integration tests for firebase?

I challenge you to rethink what you are exactly testing and why you need to perform an actual query in your unit test. This library has its own unit tests that test for that. Instead I would consider creating mock objects that resemble the data schema that you would retrieve from firestore.

@uris77
Copy link

uris77 commented Mar 30, 2021

There are sometimes need to create an integration test (that does not involve bringing up a simulator) that tests the queries. For web apps, for example, I can bring up the firebase emulator and run integration tests for the queries against it. To reiterate, I don't want to test that the library works, I want to test that:

  1. My queries work
  2. I am using the library correctly (this is useful when I'm not familiar with a library).

@russellwheatley
Copy link
Member

Hey guys, we have a page on the Flutterfire website dedicated to setting up your integration tests here. Alternatively, you can just look at the source code for Flutterfire if you wish to see how we run integration tests using the Firebase emulator suite.

@qiansen1386
Copy link

qiansen1386 commented Oct 11, 2021

@russellwheatley Come on bro, how can you close the issue, when the problem still holds??? Whenever I call initializeApp in a test file, it breaks! Are you saying the emulator approach will never work in tests?

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:firebase_core/firebase_core.dart';
void main() {
  setUpAll(() async {
    TestWidgetsFlutterBinding.ensureInitialized();
    // Expose path_provider that interlinked with Android/iOS SDK
    const MethodChannel channel =
        MethodChannel('plugins.flutter.io/path_provider');
    channel.setMockMethodCallHandler((MethodCall methodCall) async {
      return ".";
    });
    await Firebase.initializeApp();
  });
  test('Blah blah', () {});
}

@russellwheatley
Copy link
Member

Hey @qiansen1386, I'm saying that using Firebase Emulators for your integration tests will work. But the example you're using is not an integration test, it is a unit test. A unit test does not involve any native API calls (to android or iOS for example). You have to mock the calls to the native platform (i.e Firebase.initializeApp()).This file shows you how Flutterfire mocks
Firebase.initializeApp().

@qiansen1386
Copy link

@russellwheatley Thanks, I think now I understand it better. I am reimplementing my service tests under integration_test/

TBH, the unit test approach is still more preferred. The integration tests can be very slow(building + firing Android/iOS emulators), besides we just want to unit test a service, otherwise we won't use emulators.

If I mock the method calls(Firebase#initializeCore and Firebase#initializeApp) in unit test vm, can we still make calls to emulators?

Is there any hope in the future we can bypass this Android/iOS restriction?

@russellwheatley
Copy link
Member

@qiansen1386, I don't think what you want will work. The vast majority of Flutterfire's API requires interaction with the native platform. If you're not going to run an android/ios emulator, then your only other option is to mock the API calls.

@qiansen1386
Copy link

@russellwheatley Make sense, thank you a lot. I guess I have to use emulators then.

@firebase firebase locked and limited conversation to collaborators Nov 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
plugin: core type: bug Something isn't working
Projects
None yet
Development

No branches or pull requests