How to store and sync 2-3 minute educational videos in Local DB(Hive, any) Flutter for offline use with Firebase backend

22 Views Asked by At

I'm developing an educational app using Flutter where lessons are presented to users in text, video, and audio formats. These formats are synchronized to provide users with a seamless learning experience. Currently, the app fetches data from Firebase, but I'm looking to optimize it for offline usage.

I'm specifically looking for guidance on how to store videos locally using Hive or sqflite in Flutter. Each video is approximately 2 to 3 minutes long. I want the app to be able to display the locally stored data if there is no internet connection available.

Here is my code handling the remote database:

class ServiceBase {

  final Logs _logs = Get.put(Logs());

  Future<Map<String, dynamic>> getLessonsFile() async {
    final contents = await retry(
      () async => downloadFile(),
      retryIf: (e) =>
          e is SocketException ||
          e is TimeoutException ||
          e is FirebaseException,
      maxAttempts: 20,
    );

    final json = Map<String, dynamic>.from(jsonDecode(contents));
    return json;
  }

  Future<String> downloadFile() async {
    final Directory appDocDir = await getApplicationDocumentsDirectory();
    final firebase_storage.Reference ref = await getLastRemoteFile();
    final String fileName = ref.name;
    final File downloadToFile = File('${appDocDir.path}/$fileName');
    final File tempFile = File('${appDocDir.path}/$fileName.temp');

    if (!downloadToFile.existsSync()) {
      log("$fileName not  exist! Downloading .....$tempFile");
      await ref.writeToFile(tempFile).onError((error, stackTrace) async {
        await tempFile.delete();
        return throw Exception(error);
      });
      await tempFile.rename(downloadToFile.path);
      log("Download completed .....$downloadToFile");
    }

    if (downloadToFile.existsSync()) {
      log("$fileName exist! Using from cache.....$downloadToFile");
    }

    return downloadToFile.readAsString();
  }

  Future<firebase_storage.Reference> getLastRemoteFile() async {
    final firebase_storage.ListResult result = await firebase_storage
        .FirebaseStorage.instance
        .ref()
        .child("lessons")
        .listAll();

    final lessonVersions = result.items;
    lessonVersions.sort(compareIntPrefixes);

    return lessonVersions.last;
  }

  int? parseIntPrefix(String s) {
    final re = RegExp('(-?[0-9]+).*');
    final match = re.firstMatch(s);
    if (match == null) {
      return null;
    }
    return int.parse(match.group(1)!);
  }

  int compareIntPrefixes(
    firebase_storage.Reference a,
    firebase_storage.Reference b,
  ) {
    final aValue = parseIntPrefix(a.name);
    final bValue = parseIntPrefix(b.name);

    if (aValue != null && bValue != null) {
      return aValue - bValue;
    }

    if (aValue == null && bValue == null) {
      return a.name.compareTo(b.name);
    }

    if (aValue == null) {
      return 1;
    } else {
      return -1;
    }
  }
}
0

There are 0 best solutions below