-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Closed
Labels
platform: androidIssues / PRs which are specifically for Android.Issues / PRs which are specifically for Android.plugin: cloud_firestoretype: bugSomething isn't workingSomething isn't working
Description
Bug report
Describe the bug
While offline, transactions eventually start taking a very long time to fail: 10s - 30s.
Steps to reproduce
- Set up a new Firestore Flutter project
- Use the following pubspec deps:
cloud_firestore: ^2.4.0, firebase_core: ^1.4.0, firebase_auth: ^3.0.1
- Paste below code into main.dart.
- Replace the login info in main.dart with real ones.
- Build for an Android tablet (the ones I tested on was an Samsung Galaxy Tab A, and a phone: Samsung J5).
- Kill the internet for the tablet. It shouldn't matter how you do this.
- Press the blue button and wait for the transaction to fail, and note the time it takes. Do this several times.
- It should fail quick at first (30ms - 50ms), but after 6ish clicks the time will jump to 10+ seconds. The times will get progressively worse until the tablet has "rested" for a few minutes, after which it returns to failing in milliseconds and the cycle starts over.
Expected behavior
I expect it to fail immediately while offline, consistently.
Sample project
import 'dart:math';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Transaction timeout bug demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _initialization = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Container(
color: Colors.red,
child: Center(child: Text(snapshot.error.toString())),
);
}
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
return MainApp();
},
);
}
}
class MainApp extends StatefulWidget {
const MainApp({Key? key}) : super(key: key);
@override
_MainAppState createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
var _lastTransactionStart = DateTime.now();
var _lastTransactionEnd = DateTime.now();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Transaction bug demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'The last transaction took this long to fail:',
style: TextStyle(fontSize: 20),
),
Text(
_lastTransactionEnd
.difference(_lastTransactionStart)
.inMilliseconds
.toString() +
'ms',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
try {
final fs = FirebaseFirestore.instance;
_lastTransactionStart = DateTime.now();
await fs.runTransaction((trx) async {
// It doesn't appear the transactionHandler is the problem. It fails immediately.
// Doesn't matter which document, we'll never access it while offline anyway.
final ref = fs.doc('test/doc');
print('Getting a lock');
// Try to get a lock
await trx.get(ref);
print('Got lock (will never run)');
final rng = new Random();
print('Running update (will never run)');
trx.update(ref, {'test': rng.nextInt(10000)});
});
} catch (err) {
setState(() => _lastTransactionEnd = DateTime.now());
print('The last transaction took this long to fail: ' +
_lastTransactionEnd
.difference(_lastTransactionStart)
.inMilliseconds
.toString() +
'ms');
if (!err.toString().contains("transient")) print(err);
}
},
tooltip: 'Run transaction',
child: Icon(Icons.add),
),
);
}
}
Flutter doctor
Run flutter doctor
and paste the output below:
Click To Expand
[✓] Flutter (Channel stable, 2.2.3, on Mac OS X 10.13.6 17G14042 darwin-x64, locale en-DK)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[!] Xcode - develop for iOS and macOS
✗ Xcode 10.1.0 out of date (12.0.1 is recommended).
Download the latest version or update via the Mac App Store.
! CocoaPods 1.9.1 out of date (1.10.0 is recommended).
CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/platform-plugins
To upgrade see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.2)
[✓] VS Code (version 1.58.2)
[✓] Connected device (2 available)
Flutter dependencies
Run flutter pub deps -- --style=compact
and paste the output below:
Click To Expand
Dart SDK 2.13.4
Flutter SDK 2.2.3
trxtest 1.0.0+1
dependencies:
- cloud_firestore 2.4.0 [cloud_firestore_platform_interface cloud_firestore_web firebase_core firebase_core_platform_interface flutter meta]
- cupertino_icons 1.0.3
- firebase_auth 3.0.1 [firebase_auth_platform_interface firebase_auth_web firebase_core firebase_core_platform_interface flutter meta]
- firebase_core 1.4.0 [firebase_core_platform_interface firebase_core_web flutter meta]
- flutter 0.0.0 [characters collection meta typed_data vector_math sky_engine]
dev dependencies:
- flutter_test 0.0.0 [flutter test_api path fake_async clock stack_trace vector_math async boolean_selector characters charcode collection matcher meta source_span stream_channel string_scanner term_glyph typed_data]
transitive dependencies:
- async 2.6.1 [meta collection]
- boolean_selector 2.1.0 [source_span string_scanner]
- characters 1.1.0
- charcode 1.2.0
- clock 1.1.0
- cloud_firestore_platform_interface 5.3.0 [collection firebase_core flutter meta plugin_platform_interface]
- cloud_firestore_web 2.3.0 [cloud_firestore_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins js]
- collection 1.15.0
- fake_async 1.2.0 [clock collection]
- firebase_auth_platform_interface 6.0.0 [firebase_core flutter meta plugin_platform_interface]
- firebase_auth_web 3.0.0 [firebase_auth_platform_interface firebase_core firebase_core_web flutter flutter_web_plugins http_parser intl js meta]
- firebase_core_platform_interface 4.0.1 [collection flutter meta plugin_platform_interface]
- firebase_core_web 1.1.0 [firebase_core_platform_interface flutter flutter_web_plugins js meta]
- flutter_web_plugins 0.0.0 [flutter js characters collection meta typed_data vector_math]
- http_parser 4.0.0 [charcode collection source_span string_scanner typed_data]
- intl 0.17.0 [clock path]
- js 0.6.3
- matcher 0.12.10 [stack_trace]
- meta 1.3.0
- path 1.8.0
- plugin_platform_interface 2.0.1 [meta]
- sky_engine 0.0.99
- source_span 1.8.1 [collection path term_glyph]
- stack_trace 1.10.0 [path]
- stream_channel 2.1.0 [async]
- string_scanner 1.1.0 [charcode source_span]
- term_glyph 1.2.0
- test_api 0.3.0 [async boolean_selector collection meta path source_span stack_trace stream_channel string_scanner term_glyph matcher]
- typed_data 1.3.0 [collection]
- vector_math 2.1.0
MrWaggel
Metadata
Metadata
Assignees
Labels
platform: androidIssues / PRs which are specifically for Android.Issues / PRs which are specifically for Android.plugin: cloud_firestoretype: bugSomething isn't workingSomething isn't working