'Trying to show specific information when clicking in a button

I building an app that show an image from the firestore that is saved in the storage. I already can show it but i'm trying to change it when the user clicks in the button it show only some specific images.

The way i have this set up is, i have 2 lists with data for two screens. The data for the first screen

import 'package:flutter/material.dart';
import '../models/disciplinas.dart';

const DUMMY_DISCIPLINA = const [
  Disciplina(
    id: 'd1',
    title: 'Português',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Disciplina(
    id: 'd2',
    title: 'Matemática',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Disciplina(
    id: 'd3',
    title: 'Inglês',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Disciplina(
    id: 'd4',
    title: 'AI',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Disciplina(
    id: 'd5',
    title: 'PSI',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Disciplina(
    id: 'd6',
    title: 'FQ',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Disciplina(
    id: 'd7',
    title: 'Espanhol',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Disciplina(
    id: 'd8',
    title: 'ARQC',
    color: Color.fromARGB(255, 90, 57, 200),
  ),
  Disciplina(
    id: 'd9',
    title: 'RC',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Disciplina(
    id: 'd10',
    title: 'TIC',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Disciplina(
    id: 'd11',
    title: 'SO',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
];

In the screen i just create a map and show it

import 'package:flutter/material.dart';
import '../data/dummy_data.dart';
import 'disciplina_item.dart';

class DisciplinasScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //segunda base da app
      appBar: AppBar(
        //cria uma barra na parte superior da app
        title: const Text('Disciplinas'), //titulo da appbar
        toolbarHeight: 50,
      ),
      body: GridView(
        //fazer com que os buttons fiquem organizados e scrollable^
        padding: const EdgeInsets.all(25),
        children: DUMMY_DISCIPLINA //chama a lista da pagina dummy_data
            .map(
              //chama uma lista
              (dicData) => DisciplinaItem(
                //guarda na variavel 'dicData' as variveis da função DisciplinaItem da disciplina_item.dart
                dicData.id.toString(),
                dicData.title.toString(), //aponta para o title da função
                dicData.color, //aponta para a cor da função
              ),
            )
            .toList(),
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          //função do flutter que deixa mexer com a grid autonomamente
          maxCrossAxisExtent:
              200, //o maximo de width que a grid toma é de 200 pixeis
          childAspectRatio: 3 / 2, //cada grid toma o ratio de 3/2
          crossAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
          mainAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
        ),
      ),
    );
  }
}

from this

import 'package:flutter/material.dart';
import '../modulos/disciplina_modulos_screen.dart';

class DisciplinaItem extends StatelessWidget {
  //widget que não muda UI
  final String id; //id da disciplina
  final String title; //nome da disciplina
  final Color color; //cor do background do "botão"

  DisciplinaItem(
    this.id,
    this.title,
    this.color,
  ); //aponta as variaveis para a propria class

  void selectDisciplina(BuildContext ctx) {
    Navigator.of(ctx).pushNamed(
      DisciplinaModuloScreen.routeName, //route situada no main
      arguments: {
        //argumentos que vão ser passados para a outra pagina sem o utilizador ver
        'id': id,
        'title': title,
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () =>
          selectDisciplina(context), //chama a função só quando é carregado
      splashColor: Theme.of(context).primaryColor, //cor de quando é carregado
      // borderRadius: BorderRadius.circular(15), //borda redonda
      child: Container(
        padding: const EdgeInsets.all(
            15), //padding ao container de 15 pixeis em todos os lados
        child: Text(
          title,
          style: Theme.of(context).textTheme.headline6,
        ), //mostra o title no container
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [
              color.withOpacity(
                0.7,
              ), //cor que vai buscar ao ficheiro mas com opacidade reduzida
              color,
            ],
            begin: Alignment.center,
            end: Alignment.center,
          ),
          borderRadius: BorderRadius.circular(15), //botoes com bordas redondas
        ),
      ),
    );
  }
}

i also have the second screen that is also filtered with the info send the first page the screen

import 'package:flutter/material.dart';
import '../data/modulo_data.dart';
import '../modulos/modulo_item.dart';

class DisciplinaModuloScreen extends StatelessWidget {
  static const routeName = '/disciplina-modulos';
  //final String moduloId;
  //final String moduloTitle;

  //DisciplinaModuloScreen(
  //this.moduloId,
  //this.moduloTitle,
  //);

  @override
  Widget build(BuildContext context) {
    final routeArgs =
        ModalRoute.of(context)?.settings.arguments as Map<String, String>;
    final disciplinaId = routeArgs['id'];
    final disciplinaTitle = routeArgs['title'];
    final disciplinaModulo = DUMMY_MODULO.where((modulo) {
      return modulo.modDisciplinaId!.contains(disciplinaId.toString());
    }).toList();

    return Scaffold(
      appBar: AppBar(
        title: Text('Módulos da disciplina ' + disciplinaTitle.toString()),
      ),
      body: GridView.builder(
        padding: const EdgeInsets.all(25),
        gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
          //função do flutter que deixa mexer com a grid autonomamente
          maxCrossAxisExtent:
              200, //o maximo de width que a grid toma é de 200 pixeis
          childAspectRatio: 3 / 2, //cada grid toma o ratio de 3/2
          crossAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
          mainAxisSpacing: 20, //espaçamento maximo é de 20 pixeis
        ),
        itemBuilder: (ctx, index) {
          return ModuloItem(
            disciplinaModulo[index].modTitle.toString(),
            disciplinaModulo[index].color,
          );
        },
        itemCount: disciplinaModulo.length,
      ),
    );
  }
}

the list that has the data

import 'package:flutter/material.dart';
import '../../models/modulo.dart';

const DUMMY_MODULO = const [
  Modulo(
    modId: 'm1',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd8',
      'd9',
      'd10',
      'd11',
    ],
    modTitle: 'Módulo 1',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm2',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd8',
      'd9',
      'd10',
      'd11',
    ],
    modTitle: 'Módulo 2',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Modulo(
    modId: 'm3',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd8',
      'd9',
      'd10',
      'd11',
    ],
    modTitle: 'Módulo 3',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm4',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd8',
      'd9',
      'd11',
    ],
    modTitle: 'Módulo 4',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm5',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd8',
      'd9',
      'd11',
    ],
    modTitle: 'Módulo 5',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Modulo(
    modId: 'm6',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd4',
      'd5',
      'd6',
      'd7',
      'd9',
    ],
    modTitle: 'Módulo 6',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm7',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd5',
      'd6',
      'd9',
    ],
    modTitle: 'Módulo 7',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm8',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd5',
      'd6',
      'd9',
    ],
    modTitle: 'Módulo 8',
    color: Color.fromARGB(255, 90, 57, 200),
  ),
  Modulo(
    modId: 'm9',
    modDisciplinaId: [
      'd1',
      'd2',
      'd3',
      'd5',
      'd6',
      'd9',
    ],
    modTitle: 'Módulo 9',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm10',
    modDisciplinaId: [
      'd2',
      'd5',
      'd6',
    ],
    modTitle: 'Módulo 10',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm11',
    modDisciplinaId: [
      'd5',
      'd6',
    ],
    modTitle: 'Módulo 11',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Modulo(
    modId: 'm12',
    modDisciplinaId: [
      'd5',
      'd6',
    ],
    modTitle: 'Módulo 12',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm13',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 13',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm14',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 14',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Modulo(
    modId: 'm15',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 15',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm16',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 16',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
  Modulo(
    modId: 'm17',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 17',
    color: Color.fromARGB(255, 83, 48, 195),
  ),
  Modulo(
    modId: 'm18',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 18',
    color: Color.fromARGB(255, 235, 153, 46),
  ),
  Modulo(
    modId: 'm19',
    modDisciplinaId: [
      'd5',
    ],
    modTitle: 'Módulo 19',
    color: Color.fromARGB(255, 28, 209, 216),
  ),
];

The problem is that, in the screen that is supost to show the info that is flitered by the buttons in these 2 screen(the ones above this), i could only filter with a variable that i asign a value (the variable is query)

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:pap_test/upload/upload_resumos_screen.dart';

class DownloadScreen extends StatefulWidget {
  const DownloadScreen({Key? key}) : super(key: key);
  static const routeName = '/downlaod-resumos';

  @override
  State<DownloadScreen> createState() => _DownloadScreenState();
}

class _DownloadScreenState extends State<DownloadScreen> {
  // variavel que vai ser usada para procurar na base de dados
  String query = '1';

  // guardar o caminho da base de dados na variavel _firebaseFirestore
  CollectionReference _firebaseFirestore =
      FirebaseFirestore.instance.collection('images');

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Resumos'),
      ),
      // streamBuilder é usado para auto se construir de acordo com o snapshot(data recebida da base de dados)
      body: StreamBuilder<QuerySnapshot>(
        stream: _firebaseFirestore.snapshots().asBroadcastStream(),
        builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
          // se o snapshot for null mostra o simbolo de loading
          if (!snapshot.hasData) {
            return Center(
              // simbolo de loding
              child: CircularProgressIndicator(),
            );
          } else {
            if (snapshot.data!.docs
                .where((QueryDocumentSnapshot<Object?>
                        element) => // campo da firestore
                    element['disciplina']
                        // como o campo é int tem que se passar para string
                        .toString()
                        .toLowerCase()
                        // onde (where) tiver (contains) a query igual ao que está nas disciplina
                        .contains(query.toLowerCase()))
                .isEmpty) {
              return Center(
                child: Text(
                  'Por aqui está muito lento, carrega no botão e publica um resumo.',
                  style: Theme.of(context).textTheme.headline5,
                  textAlign: TextAlign.center,
                ),
              );
            } else {
              return ListView(
                children: [
                  // os ... permite nos adicinar varios widgets
                  // onde o campo da firestore disciplina for igual ao que está no query ele cria um mapa
                  ...snapshot.data!.docs
                      .where((QueryDocumentSnapshot<Object?>
                              element) => // campo da firestore
                          element['disciplina']
                              // como o campo é int tem que se passar para string
                              .toString()
                              .toLowerCase()
                              // onde (where) tiver (contains) a query igual ao que está nas disciplina
                              .contains(query.toLowerCase()))
                      .map(
                    (QueryDocumentSnapshot<Object?> data) {
                      // guarda na variavel disciplina o que esta na firestore
                      final String descricao = data.get('descricao');
                      // guarda na variavel image o que esta na firestore
                      final image = data['url'];
                      // depois cria um ListTile em relação á data dada em cima
                      return ListTile(
                        onTap: () async {
                          //await FirebaseApi.downloadFile();
                          // fazer o downLoad
                        },
                        // mostra a imagem
                        leading: CircleAvatar(
                          backgroundImage: NetworkImage(image),
                        ),

                        // mostra a disciplina
                        title: Text(
                          descricao.toString(),
                          style: Theme.of(context).textTheme.headline5,
                        ),
                      );
                    },
                  )
                ],
              );
            }

            // se nao for nulo
            // fetch data
            // mostra a data na consola
            print(snapshot.data);
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // quando o botao é precionado vai para o UploadScreen
          Navigator.of(context).pushNamed(UploadResumoScreen.routeName);
        },
        //cor do background
        backgroundColor: Color.fromARGB(255, 28, 209, 216),
        // tipo do icon
        child: const Icon(Icons.add),
        // cor do icon
        foregroundColor: Colors.white,
      ),
    );
  }
}

class QueryMod {
  const QueryMod(this.mod);

  final String mod;
}

class QueryDisc {
  const QueryDisc(this.disc);

  final String disc;
}

if it can help, i'm uploading the images with this code (i passed the characters limit so the upload is in here https://drive.google.com/file/d/1yb9_3IrEzrkT37zpfLwkwxb7QYKU_k0e/view?usp=sharing )



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source