2

I'm attempting to, in the prepare method of the main channel, load up an AutoRefreshingAuthClient and subsequently a FirestoreAPI object, but I am getting the following stack trace:

Unhandled exception:
Bad state: Future already completed
#0      _Completer.completeError (dart:async/future_impl.dart:21:31)
#1      ApplicationIsolateSupervisor._handleIsolateException (package:aqueduct/src/application/isolate_supervisor.dart:129:24)
#2      ApplicationIsolateSupervisor.listener (package:aqueduct/src/application/isolate_supervisor.dart:102:7)
#3      _RootZone.runUnaryGuarded (dart:async/zone.dart:1314:10)
#4      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:336:11)
#5      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:263:7)
#6      _SyncStreamController._sendData (dart:async/stream_controller.dart:764:19)
#7      _StreamController._add (dart:async/stream_controller.dart:640:7)#8      _StreamController.add (dart:async/stream_controller.dart:586:5)
#9      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)

Though this stack trace does not point to anything in my code, I isolated the issue to an awaited clientViaServiceAccount call (code below) in the prepare method.

I'm unsure as to what I'm doing wrong as the documentation for this API (googleapis) is largely unhelpful in this context, and the example method shown in the documentation doesn't seem to work here.

How do I properly set up the AutoRefreshingAuthClient and FirestoreAPI objects without getting this exception?

This is an Aqueduct project that has no issues running if I simply run the example code shipped with the project at creation.

I've tried shifting the calls and initialization to different scopes, but aside from that I don't know what to try.

channel.dart

import 'dart:io';

import 'package:googleapis/firestore/v1.dart';
import 'package:googleapis_auth/auth.dart';
import 'package:googleapis_auth/auth_io.dart';

import 'package:mm_block/mm_block.dart';
import 'package:mm_block/controller/member.dart';

final _credentials = ServiceAccountCredentials.fromJson(
  File('credentials').readAsString()
);
final _scopes = [
  FirestoreApi.CloudPlatformScope
];

class MMBlockChannel extends ApplicationChannel {
  FirestoreApi firestore;

  @override
  Future prepare() async {
    // The issue is here.
    await clientViaServiceAccount(_credentials, _scopes)
      .then((client) => firestore = FirestoreApi(client));
  }

  ...
}

This should all run correctly and I should end up with an AutoRefreshingAuthClient being passed to the FirestoreAPI call.

glotchimo
  • 664
  • 5
  • 23
  • What happens when you move this line of code to a simple Dart script? If you are using await, you don't need to use .then. Just assign the return of await clientViaServiceAccount(...) to a variable and then pass that variable to FirestoreApi's constructor. – Joe Conway Apr 10 '19 at 17:25

0 Answers0