How to handle firestore get request properly

  Kiến thức lập trình

I’m currently dealing with firestore read and riverpod for state management.

I used ChangeNotifier (which is deprecated and not recommend using) to notify home screen to reload based on navigation. The problem is whenever it reload, the HomeScreen initState is executed again (I think the Widget is reinserted into the Widget Tree) so my getData function is execute, which I do not want.

What is the solution to deal with this? Should i move the getData fn outside of this or change how I fetch data inside widget? Appreciate your help
My code

import 'dart:developer';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:webtoon/firebase/cloud_store/store.dart';

import '../../model/playlist.dart';
import '../../model/song.dart';
import '../../utilities/fonts.dart';
import 'widgets/playlist_info.dart';
import 'widgets/song_info.dart';

class HomeUI extends StatefulWidget {
  const HomeUI({super.key});

  @override
  State<HomeUI> createState() => _HomeUIState();
}

class _HomeUIState extends State<HomeUI> {
  bool isLoading = true;
  final List<Song> songs = [];

  Future<void> getSong() async {
    final querySnapshot = await FirebaseFirestore.instance
        .collection('Songs')
        .where('genres', arrayContains: 'Pop')
        .get();
    for (var docSnapshot in querySnapshot.docs) {
      final String songUrl = await Storage.getSongUrl(docSnapshot['title']);
      final String imageUrl = await Storage.getSongAvatarUrl(docSnapshot['title']);
      songs.add(Song.fromJson(docSnapshot, imageUrl, songUrl));
    }
  }

  @override
  void initState() {
    super.initState();
    getSong().then((value) => setState(() {
          isLoading = false;
        }));
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Padding(
        padding: const EdgeInsets.only(right: 20.0, left: 20.0),
        child: Column(
          children: <Widget>[
            const SizedBox(height: 20),
            isLoading
                ? const CircularProgressIndicator()
                : SizedBox(
                    height: 240,
                    child: ListView.separated(
                      separatorBuilder: (BuildContext context, int index) {
                        return const SizedBox(width: 30);
                      },
                      itemCount: songs.length,
                      scrollDirection: Axis.horizontal,
                      itemBuilder: (context, index) =>
                          SongInfo(song: songs.elementAt(index)),
                    ),
                  ),
          ],
        ),
      ),
    );
  }
}

LEAVE A COMMENT