Home > OS >  Flutter/Firebase - Pressing on TextField opens device's keyboard & rebuilds widget issue
Flutter/Firebase - Pressing on TextField opens device's keyboard & rebuilds widget issue

Time:11-18

To briefly explain the code, we have a simple stream builder which fetches data in the Firestore Database and then we return and display the value of 'username' on the screen.

We also have a TextField in the same widget & I've noticed that whenever I click on it, it seems to rebuild and fetch the data again. The goal would be to avoid rebuilding whenever the device's keyboard opens or closes as this would cost unnecessary reads. Any idea how I can achieve the same result but without the rebuilding effect?

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import '../models/user.dart';

class Admin extends StatefulWidget {
  const Admin({
    Key? key,
  }) : super(key: key);

  @override
  State<Admin> createState() => _AdminState();
}

class _AdminState extends State<Admin> {
  final TextEditingController _userController = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
            elevation: 4,
            toolbarHeight: 50,
            backgroundColor: Colors.white,
            actions: [
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 12),
                width: MediaQuery.of(context).size.width,
                child: const Text('Admin',
                    style: TextStyle(
                        color: Colors.black,
                        fontSize: 20,
                        letterSpacing: 0.3,
                        fontWeight: FontWeight.w500)),
              ),
            ]),
        body: Column(
          children: [
            TextField(
              controller: _userController,
              decoration: InputDecoration(
                labelText: 'User',
              ),
            ),
            StreamBuilder(
              stream: FirebaseFirestore.instance
                  .collection('users')
                  .limit(1)
                  .snapshots(),
              builder: (context,
                  AsyncSnapshot<QuerySnapshot<Map<String, dynamic>>> snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return Row();
                }
                return snapshot.data?.docs.length != 0
                    ? SingleChildScrollView(
                        child: ListView.builder(
                          physics: const NeverScrollableScrollPhysics(),
                          shrinkWrap: true,
                          itemCount: snapshot.data?.docs.length,
                          itemBuilder: (context, index) {
                            User user = User.fromSnap(
                              snapshot.data!.docs[index],
                            );

                            return Text('${user.username}');
                          },
                        ),
                      )
                    : Row();
              },
            ),
          ],
        ),
      ),
    );
  }
}

CodePudding user response:

Try converting your class to a stateless widget

CodePudding user response:

To stop fetching data repeatedly you can do one thing here instead of making a call to firebasefirestore from stream build you can do it in void initState() method and store it data in a variable

Add this code above build method

late dynamic streamData;

@override
void initState() {
  super.initState();
  streamData = FirebaseFirestore.instance
                  .collection('users')
                  .limit(1)
                  .snapshots();

}

and just replace this code

stream: FirebaseFirestore.instance
              .collection('users')
              .limit(1)
              .snapshots(),

with this

stream : streamData,
  • Related