firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.5k stars 3.92k forks source link

🐛 [firebase_storage] Firebase Storage doesn't enforce retry when the internet connection lost on iOS #10852

Open vnguyenorangebees opened 1 year ago

vnguyenorangebees commented 1 year ago

Bug report

Describe the bug On Android, when the internet connection lost while uploading, Exponential Backoff mechanism is enforced to retry the task. I will return retry-limit-exceeded code if the maxUploadRetryTime reached.

Screenshot 2023-04-26 at 3 17 02 PM Screenshot 2023-04-26 at 3 23 17 PM

However, with the same upload task on iOS, after the internet connection lost, no retry attempts were made and the task never returns the timeout error.

Steps to reproduce

Steps to reproduce the behavior:

  1. Set setMaxUploadRetryTime() and setMaxDownloadRetryTime() for 1 minute
  2. Start an upload task with the internet connection.
  3. Turn off the internet connection.
  4. Observe the logs to see the difference between two platforms.

Expected behavior

iOS should also retry and return timeout error like Android.


Flutter doctor

Run flutter doctor and paste the output below:

Click To Expand ``` [!] Flutter (Channel stable, 3.7.3, on macOS 13.3.1 22E261 darwin-arm64, locale en-US) • Flutter version 3.7.3 on channel stable at /Users/vunguyen/development/flutter ! Warning: `dart` on your path resolves to /usr/local/Cellar/dart/2.17.6/libexec/bin/dart, which is not inside your current Flutter SDK checkout at /Users/vunguyen/development/flutter. Consider adding /Users/vunguyen/development/flutter/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 9944297138 (3 months ago), 2023-02-08 15:46:04 -0800 • Engine revision 248290d6d5 • Dart version 2.19.2 • DevTools version 2.20.1 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/vunguyen/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java • Java version Java(TM) SE Runtime Environment (build 1.8.0_361-b09) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14E222b • CocoaPods version 1.11.3 [✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome) ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable. [!] Android Studio (version 2022.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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [✓] VS Code (version 1.77.3) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension can be installed from: 🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [✓] Connected device (3 available) • Redmi Note 8 Pro (mobile) • yh9l79mf4xcaxspf • android-arm64 • Android 11 (API 30) • Vu’s iPhone 14 Pro Max (mobile) • 00008120-0011658C349B401E • ios • iOS 16.4.1 20E252 • macOS (desktop) • macos • darwin-arm64 • macOS 13.3.1 22E261 darwin-arm64 ! Error: Vu’s Apple Watch needs to connect to determine its availability. Check the connection between the device and its companion iPhone, and the connection between the iPhone and Xcode. Both devices may also need to be restarted and unlocked. (code 1) [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 3 categories. ```

Flutter dependencies

Run flutter pub deps -- --style=compact and paste the output below:

Click To Expand ``` - firebase_auth 4.4.2 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta] - firebase_core 2.10.0 [firebase_core_platform_interface firebase_core_web flutter meta] - firebase_crashlytics 3.1.1 [firebase_core firebase_core_platform_interface firebase_crashlytics_platform_interface flutter stack_trace] - firebase_remote_config 4.0.1 [firebase_core firebase_core_platform_interface firebase_remote_config_platform_interface firebase_remote_config_web flutter] - firebase_storage 11.1.1 [firebase_core firebase_core_platform_interface firebase_storage_platform_interface firebase_storage_web flutter] - firebase_storage_mocks 0.6.1 [flutter firebase_storage] ```

darshankawar commented 1 year ago

Thanks for the report @vnguyenorangebees Can you provide a complete minimal reproducible code sample that shows the reported behavior ?

vnguyenorangebees commented 1 year ago

Thanks for the report @vnguyenorangebees Can you provide a complete minimal reproducible code sample that shows the reported behavior ?

This can be reproduced with the example code from: https://firebase.google.com/docs/storage/flutter/upload-files as long as the internet connection is switched on/off.

final appDocDir = await getApplicationDocumentsDirectory();
final filePath = "${appDocDir.absolute}/path/to/mountains.jpg";
final file = File(filePath);

// Create the file metadata
final metadata = SettableMetadata(contentType: "image/jpeg");

// Create a reference to the Firebase Storage bucket
final storageRef = FirebaseStorage.instance.ref();

// Upload file and metadata to the path 'images/mountains.jpg'
final uploadTask = storageRef
    .child("images/path/to/mountains.jpg")
    .putFile(file, metadata);

// Listen for state changes, errors, and completion of the upload.
uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) {
  switch (taskSnapshot.state) {
    case TaskState.running:
      final progress =
          100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes);
      print("Upload is $progress% complete.");
      break;
    case TaskState.paused:
      print("Upload is paused.");
      break;
    case TaskState.canceled:
      print("Upload was canceled");
      break;
    case TaskState.error:
      // Handle unsuccessful uploads
      break;
    case TaskState.success:
      // Handle successful uploads on complete
      // ...
      break;
  }
});
darshankawar commented 1 year ago

Thanks for the update. Using the code sample above, seeing the same behavior as reported while trying to upload a file with switched off network connection.

DimaLiubko commented 2 weeks ago

Hello! Do we have a solution to fix this case?