Is there a way to skip await if it's too long? (Flutter)

101

Solution 1

Pass your Firebase api call to a function, make the method return future,

Future<String?> getData() async {
await FirebaseDatabase.instance.ref().child("data").once().then((snapshot) {
     Map data = snapshot.snapshot.value as Map;
     return jsonEncode(data);
  });
}

Then on main method, attach a timeout with that method you created

void main() async {

  await Firebase.initializeApp();

  String? x = await getData().timeout(Duration(seconds: 5), onTimeout: () { 
  return null };

  return ChangeNotifierProvider<DataModel>.value(
     value: DataModel(data: x),
     child: MaterialApp()
  );
}

So if you api takes more then 5 seconds of time, then it exit and return null

Solution 2

you can User Race condition or Future.timeout

Race condition using future.any

final result = await Future.any([
  YourFunction(),
  Future.delayed(const Duration(seconds: 3))
]);

in above code one who finish first will give result, so if your code takes more than 3 sec than other function will return answer

Share:
101
Kucing Malaya
Author by

Kucing Malaya

Updated on January 04, 2023

Comments

  • Kucing Malaya
    Kucing Malaya over 1 year

    I use async await in main so the user has to wait in the splash screen before entering the app.

    void main() async {
    
      await Firebase.initializeApp();
    
      String? x;
      await FirebaseDatabase.instance.ref().child("data").once().then((snapshot) {
         Map data = snapshot.snapshot.value as Map;
         x = jsonEncode(data);
      });
    
      return ChangeNotifierProvider<DataModel>.value(
         value: DataModel(data: x),
         child: MaterialApp()
      );
    }
    

    If there are users entering the app without an internet connection, they will be stuck on the splash screen forever. If there are also users with slow internet connection, they will be stuck on the splash screen longer.

    So no matter what the internet connection problem is, I want to set a maximum of 5 seconds only to be in the await, if it exceeds, skip that part and go straight into the app.

    • Frank van Puffelen
      Frank van Puffelen about 2 years
      When I tested once() earlier today without an internet connection it actually threw an error: "Error: [firebase_database/unknown] Error: Client is offline.". See stackoverflow.com/questions/71453567/… for my test.
    • Kucing Malaya
      Kucing Malaya about 2 years
      @FrankvanPuffelen Yup, stuck on the splash screen all the time even using try-catch-finally and .catchError(). I think there is no solution yet to catch internet connection error. timeout solved my problem.
  • Kucing Malaya
    Kucing Malaya about 2 years
    Thanks! timeout can also be handled if there is no internet connection since we cannot catch the 'no internet' error.