flutter_isolate icon indicating copy to clipboard operation
flutter_isolate copied to clipboard

Saving data to Firestore not working ONLY ON PRODUCTION

Open eduardothiesen opened this issue 2 years ago • 17 comments

Hi,

I'm using the FlutterIsolates to save mass data to my Firestore server. When I test it running from Android Studio, it works perfectly. But, when I send it to Internal Test, the data never reaches the firestore server.

void saveStall(String payload) async {
  final mainIsolatePort = ReceivePort();
  final saveIsolate = await FlutterIsolate.spawn(
      saveStallToFirestore, mainIsolatePort.sendPort);

  mainIsolatePort.listen(
      (messageFromSaveIsolate) {
        if (messageFromSaveIsolate is SendPort) {
          messageFromSaveIsolate.send(payload);
        }

        if (messageFromSaveIsolate is String) {
          if (messageFromSaveIsolate == 'ok') {
            saveIsolate.kill();
            mainIsolatePort.close();
          } else {
            //TODO: treat error
          }
        }
      },
      onDone: () {},
      onError: (e) {
        saveIsolate.kill();
        mainIsolatePort.close();
      });
}

saveStallToFirestore(SendPort mainIsolatePort) async {
  final saveStallToFirebaseIsolatePort = ReceivePort();
  try {
    mainIsolatePort.send(saveStallToFirebaseIsolatePort.sendPort);

    saveStallToFirebaseIsolatePort.listen((messageFromMainIsolate) async {
      if (messageFromMainIsolate is String) {
        var json = jsonDecode(messageFromMainIsolate, reviver: dateDecoder);

        WidgetsFlutterBinding.ensureInitialized();
        await Firebase.initializeApp();
        StallRepository.instance.update(
            farmId: json['farmId'], id: json['id'], json: json['stall']);
        List<dynamic> ovines =
            json['ovines'].map((e) => Ovine.fromJson(e['id'], e)).toList();
        for (Ovine o in ovines) {
          OvineRepository.instance
              .update(farmId: json['farmId'], id: o.id, json: o.toJson());
        }
        mainIsolatePort.send('ok');
      }
    });
  } catch (err) {
    mainIsolatePort.send('error');
  }
}

//Method called by OvineRepository.instance.update in the above snippet
Future<void>? update(
      {required String farmId,
      required String id,
      required Map<String, dynamic> json,
      SendPort? messenger}) {
    try {
      var result = FirebaseFirestore.instance
          .collection(farmsCollectionKey)
          .doc(farmId)
          .collection(ovinesCollectionKey)
          .doc(id)
          .update(json);
      if (messenger != null) {
        messenger.send('ok');
      }
      return result;
    } catch (e) {
      Get.snackbar(
        'error'.tr,
        e.toString(),
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.white,
        colorText: Colors.black,
      );

      return null;
    }
  }

Any ideas what I may be doing wrong? Thanks in advance.

eduardothiesen avatar Jun 24 '22 13:06 eduardothiesen

Does it work outside an isolate?

On 24 Jun 2022, at 9:17 PM, Carlos Eduardo Gomes Thiesen @.***> wrote:

 Hi,

I'm using the FlutterIsolates to save mass data to my Firestore server. When I test it running from Android Studio, it works perfectly. But, when I send it to Internal Test, the data never reaches the firestore server.

` void saveStall(String payload) async { final mainIsolatePort = ReceivePort(); final saveIsolate = await FlutterIsolate.spawn( saveStallToFirestore, mainIsolatePort.sendPort);

mainIsolatePort.listen( (messageFromSaveIsolate) { if (messageFromSaveIsolate is SendPort) { messageFromSaveIsolate.send(payload); }

if (messageFromSaveIsolate is String) {
  if (messageFromSaveIsolate == 'ok') {
    saveIsolate.kill();
    mainIsolatePort.close();
  } else {
    //TODO: treat error
  }
}

}, onDone: () {}, onError: (e) { saveIsolate.kill(); mainIsolatePort.close(); }); }

saveStallToFirestore(SendPort mainIsolatePort) async { final saveStallToFirebaseIsolatePort = ReceivePort(); try { mainIsolatePort.send(saveStallToFirebaseIsolatePort.sendPort);

saveStallToFirebaseIsolatePort.listen((messageFromMainIsolate) async { if (messageFromMainIsolate is String) { var json = jsonDecode(messageFromMainIsolate, reviver: dateDecoder);

WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
StallRepository.instance.update(
    farmId: json['farmId'], id: json['id'], json: json['stall']);
List<dynamic> ovines =
    json['ovines'].map((e) => Ovine.fromJson(e['id'], e)).toList();
for (Ovine o in ovines) {
  OvineRepository.instance
      .update(farmId: json['farmId'], id: o.id, json: o.toJson());
}
mainIsolatePort.send('ok');

} }); } catch (err) { mainIsolatePort.send('error'); } }

//Method called by OvineRepository.instance.update in the above snippet Future? update( {required String farmId, required String id, required Map<String, dynamic> json, SendPort? messenger}) { try { var result = FirebaseFirestore.instance .collection(farmsCollectionKey) .doc(farmId) .collection(ovinesCollectionKey) .doc(id) .update(json); if (messenger != null) { messenger.send('ok'); } return result; } catch (e) { Get.snackbar( 'error'.tr, e.toString(), snackPosition: SnackPosition.TOP, backgroundColor: Colors.white, colorText: Colors.black, );

return null; } } `

Any ideas what I may be doing wrong? Thanks in advance.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.

nmfisher avatar Jun 24 '22 14:06 nmfisher

@nmfisher yes, they work outside the isolate in production. Inside only when debbuging

eduardothiesen avatar Jun 24 '22 14:06 eduardothiesen

Here's my flutter doctor (obs: I also tested in stable branch, same issue)

[✓] Flutter (Channel master, 3.1.0-0.0.pre.1358, on macOS 12.4 21F79 darwin-x64, locale en-BR)
    • Flutter version 3.1.0-0.0.pre.1358 on channel master at /Users/eduardothiesen/developer/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 9f4b9bfd49 (21 hours ago), 2022-06-23 12:27:09 -0500
    • Engine revision fc08bf45b0
    • Dart version 2.18.0 (build 2.18.0-216.0.dev)
    • DevTools version 2.14.0

[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
    • Android SDK at /Users/eduardothiesen/Library/Android/sdk
    • Platform android-32, build-tools 32.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 13E113
    • CocoaPods version 1.11.3

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

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] Connected device (3 available)
    • SM G985F (mobile) • RQ8N403TWZL • android-arm64  • Android 12 (API 31)
    • macOS (desktop)   • macos       • darwin-x64     • macOS 12.4 21F79 darwin-x64
    • Chrome (web)      • chrome      • web-javascript • Google Chrome 103.0.5060.53

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

And pub spec

version: 1.0.0+1

environment:
  sdk: ">=2.14.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  # Core
  collection: ^1.16.0
  flutter_facebook_auth: ^4.0.0
  get: ^4.6.1
  get_storage: ^2.0.3
  google_sign_in: ^5.2.1
  http: ^0.13.4
  intl: ^0.17.0
  flutter_isolate: ^2.0.2
  package_info_plus: ^1.4.2
  path_provider: ^2.0.5
  path_provider_platform_interface: ^2.0.4
  purchases_flutter: ^3.10.0
  sign_in_with_apple: ^4.0.0
  uuid: ^3.0.4

  # Firebase
  cloud_firestore:
  cloud_functions: ^3.1.1
  firebase_analytics: ^9.0.4
  firebase_auth: ^3.3.17
  firebase_core: ^1.16.0
  firebase_crashlytics: ^2.2.0

  # Icons
  cupertino_icons: ^1.0.2
  font_awesome_flutter: ^8.11.0

  # Miscellaneous
  connectivity_plus: ^2.3.0
  device_info_plus: ^4.0.0
  g_recaptcha_v3: ^0.0.4
  universal_html: ^2.0.8
  url_launcher: ^6.0.12

  # UI
  country_code_picker: ^2.0.2
  easy_mask: ^2.0.1
  flutter_typeahead: ^4.0.0
  modal_progress_hud_nsn: ^0.2.1
  syncfusion_flutter_charts: ^20.1.52

  # Utils
  crypto: ^3.0.1
  extension_google_sign_in_as_googleapis_auth: ^2.0.4
  googleapis: ^9.1.0
  syncfusion_flutter_xlsio: ^20.1.52-beta

dependency_overrides:
  font_awesome_flutter:
    path: "../font_awesome_flutter-master"

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^2.0.1

eduardothiesen avatar Jun 24 '22 14:06 eduardothiesen

Have you tried calling await Firebase.initializeApp(); in the main isolate before trying to save anything in the spawned isolate?

nmfisher avatar Jun 24 '22 15:06 nmfisher

@nmfisher thanks for the suggestion. I tried now and received the following error: Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

eduardothiesen avatar Jun 24 '22 20:06 eduardothiesen

Do you have authentication set up on your Firebase database, and if so, how/where in the app are you authenticating?

On 25 Jun 2022, at 4:16 AM, Carlos Eduardo Gomes Thiesen @.***> wrote:  @nmfisher thanks for the suggestion. I tried now and received the following error: Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

nmfisher avatar Jun 25 '22 03:06 nmfisher

Yes, I have authentication set up. When the user opens the app a listener checks the firebase credentials and if they are not valid, routes the user to the auth screen. It does not happen inside an isolate though

eduardothiesen avatar Jun 25 '22 21:06 eduardothiesen

Sorry I did reply to this via e-mail but it looks like GitHub didn't put it through.

Can you try manually authenticating to Firebase inside the same isolate before saving the data?

nmfisher avatar Jun 28 '22 14:06 nmfisher

Hi @nmfisher. That happened to me too ;D

I'll test that as soon as I can. But I don't see this working in a real scenario, since I have authentication via phone number, email and social networks.

eduardothiesen avatar Jun 30 '22 18:06 eduardothiesen

Was this resolved?

nmfisher avatar Jul 08 '22 14:07 nmfisher

Hey @nmfisher . I didn't have a change to test your latest suggestion. But, as I mentioned, it would not be a viable solution in my case. The funny thing is that I used flutter_isolate for a few weeks in production working perfectly. And now it only works in debug.

My solution was to remodel my database to have smaller objects.

Thanks for the attention and help.

eduardothiesen avatar Jul 08 '22 14:07 eduardothiesen

That was not a solution, it was a debugging step to check whether authenticating to a Firebase instance outside an isolate also authenticates to the instance inside the isolate (I suspect it doesn't). I will leave this open so if anyone has a similar problem in future, please try this first and report here.

nmfisher avatar Jul 09 '22 00:07 nmfisher

Try this PR, it might fix it. https://github.com/rmawatson/flutter_isolate/pull/118

srmncnk avatar Sep 06 '22 09:09 srmncnk

I have the same problem. The app is working in debug model but not in release mode. Could you please publish a new version with the proposed fix?

deadsoul44 avatar Sep 23 '22 21:09 deadsoul44

Yes, I have authentication set up. When the user opens the app a listener checks the firebase credentials and if they are not valid, routes the user to the auth screen.

Em sáb., 25 de jun. de 2022 00:31, Nick Fisher @.***> escreveu:

Do you have authentication set up on your Firebase database, and if so, how/where in the app are you authenticating?

On 25 Jun 2022, at 4:16 AM, Carlos Eduardo Gomes Thiesen @.***> wrote:  @nmfisher thanks for the suggestion. I tried now and received the following error: Unhandled Exception: [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp()

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

— Reply to this email directly, view it on GitHub https://github.com/rmawatson/flutter_isolate/issues/112#issuecomment-1166182147, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABR3LYEDLHM6HD5GHT4HUN3VQZ4RPANCNFSM5ZX2L5AA . You are receiving this because you authored the thread.Message ID: @.***>

eduardothiesen avatar Oct 11 '22 08:10 eduardothiesen

Can you try manually authenticating to Firebase inside the same isolate before saving the data?

On 26 Jun 2022, at 5:32 AM, Carlos Eduardo Gomes Thiesen @.***> wrote:

 Yes, I have authentication set up. When the user opens the app a listener checks the firebase credentials and if they are not valid, routes the user to the auth screen. It does not happen inside an isolate though

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.

nmfisher avatar Oct 11 '22 08:10 nmfisher

@eduardothiesen we've recently published fixes for issues running Flutter > 3.3 in release mode, can you advise if these have fixed your issue?

nmfisher avatar Nov 12 '22 06:11 nmfisher