Search code examples
flutterfirebasedarttestingflutter-test

Log in Firebase auth and get Id token in flutter tests


I would like to write some integration tests for an app that I am creating in flutter.

I would like to check the integration between frontend and backend, and in order to do so, I need to generate a valid JWT Id Token from Firebase (from tests credentials, that will be managed as secrets, but this is out of scope of this question).

Note: I know that all my libraries are up to date (the same error message is sometimes raised when some dependencies are out of date), because my login / JWT generation and retrieval do work well in the actual app when I launch it in a simulator.

I encounter an issue when trying to run the canonical way of login in and getting the id token in test.

So far, I have written my tests as follow, but they do raise an error when I try to run them:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;

// + some custom imports for type SingleRecipientMessageHeader, etc...

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();
  
  group('messageRepository', () {
    late final String? jwt;
    
    setUp(() async {
      await Firebase.initializeApp(
        options: DefaultFirebaseOptions.android,
      );  // <= this command raises the error!
      final instance = firebase_auth.FirebaseAuth.instance;

      await instance.signInWithEmailAndPassword(
          email: "<REDACTED>", password: "<REDACTED>");
      jwt = await instance.currentUser?.getIdToken();
    });

    tearDown(() {});

    test('message repository dummy test', () async {
      List<SingleRecipientMessageHeader> messages =
          await MessageRepository().fetchMessages(jwt!);
      ...  // the actual integration tests follow...
    });
  });
}

However, when I try to run those tests, the command flagged above raises the following error:

PlatformException(channel-error, Unable to establish connection on channel., null, null)
package:firebase_core_platform_interface/src/pigeon/messages.pigeon.dart 203:7  FirebaseCoreHostApi.initializeCore

From what I understand, when running tests, no actual platform exist, hence the connection error.

Does anyone know how I could achieve login in and getting the JWT Id token from Firebase in my test suite ?

Thanks a lot!


Solution

  • I finally managed to get a jwt for my tests, by calling the Firebase API, as per the Firebase documentation:

    import 'package:flutter_test/flutter_test.dart';
    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    // + some custom imports for type SingleRecipientMessageHeader, etc...
    
    void main() {
      
      group('messageRepository', () {
        late final String? jwt;
    
      setUp(() async {
          http.Response response = await http.post(
            Uri.parse(
                'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=<MY API KEY>'),
            headers: <String, String>{},
            body: jsonEncode(<String, String>{
              'email': '<REDACTED>',
              'password': '<REDACTED>',
              'returnSecureToken': 'true',
            }),
          );
          jwt = jsonDecode(response.body)['idToken'];
        });
    
        tearDown(() {});
    
        test('message repository dummy test', () async {
          List<SingleRecipientMessageHeader> messages =
              await MessageRepository().fetchMessages(jwt);
          expect(messages[0].headerStatus, HeaderStatus.active);
        // the actual integration tests follow...
        });
      });
    }