Getting document from Firestore only 1 time

435 views
Skip to first unread message

Alvaro Gonzalez Rico

unread,
Apr 6, 2021, 9:45:55 AM4/6/21
to Flutter Development (flutter-dev)
Hello! I'm trying to get the 'username' of the current user from the users database on Firestore. I only need to get it once (NO need for streambuilder, futurebuilder, etc). I only need the 'username' to make it appear on the UI 1 time and it will not change depending on the activity, meaning that once I get the 'username' from the database, it will always stay the same. I'm currently using the code below, BUT I think I'm overcomplicating myself. Also, if I use the code below, I have a problem because I have a future String that I want to place in a String variable (so it is not letting me use it). What is a more simple way to get the 'username' 1 time from the users database? Thanks

Future<String> getCurrentUserData() async{
    final String userId = user.uid;
    DocumentSnapshot snapshot = await FirebaseFirestore.instance.collection('users').doc(userId).get();
    return currentUsername = snapshot['username'];
  }

Suzuki Tomohiro

unread,
Apr 6, 2021, 10:14:43 AM4/6/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
Use FutureBuilder.
(I wonder why you say you don’t need FutureBuilder)

--
You received this message because you are subscribed to the Google Groups "Flutter Development (flutter-dev)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flutter-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/flutter-dev/fa4259c9-de7d-4c3b-8d2e-1969d7f29ccdn%40googlegroups.com.

Alvaro Gonzalez Rico

unread,
Apr 6, 2021, 10:24:46 AM4/6/21
to Flutter Development (flutter-dev)
Hello! I may be mistaken, but since I only need the value of the currentuser username, it is going to be the same no matter what the user does within the app, so why would I need a futurebuilder if I am not building anything. If his username is Bob99, I only want to get Bob99 in a string variable called username. The username Bob99 is never going to change and I am not building anything. I just want to save Bob99 is a variable, in case a need it later on. 

Suzuki Tomohiro

unread,
Apr 6, 2021, 10:59:08 AM4/6/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
OK, then use FutureBuilder.
Let me know how your perception changes or not after you implement it with FutureBuilder.

Alvaro Gonzalez Rico

unread,
Apr 6, 2021, 11:46:39 AM4/6/21
to Flutter Development (flutter-dev)
Hello, I still do not understand why I would need to use FutureBuilder to do "final String username = username from database that I only need to get one time"?

Suzuki Tomohiro

unread,
Apr 6, 2021, 12:13:28 PM4/6/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
Because you don’t have the user name first time. Please implement it with FutureBuilder now. I’ll don’t answer your question until you show me you’re using FutureBuilder.

Alvaro Gonzalez Rico

unread,
Apr 7, 2021, 8:50:53 AM4/7/21
to Flutter Development (flutter-dev)
Hello! I'm trying to implement it with a FutureBuilder, but I need to return a widget, which is something I do not have. I just need to save the username one time to then use it throughout the app. This is what I have right now: it returns a Future String, which gives me problems to then use it on String variables.

Future<String> getCurrentUserData() async{
    final String userId = user.uid;
    final userData = await FirebaseFirestore.instance.collection('users').doc(userId).get();
    return currentUsername = userData.data()['username'];
  } 

Suzuki Tomohiro

unread,
Apr 7, 2021, 8:57:36 AM4/7/21
to Flutter Development (flutter-dev)
You said you want to make the user name appear in the UI. Please implement that using FutureBuilder first.

Once you know how to use FutureBuilder, let’s think about the database stuff.

Alvaro Gonzalez Rico

unread,
Apr 7, 2021, 9:56:50 AM4/7/21
to Flutter Development (flutter-dev)
Below is what I have right now. What I am trying to do is get all the userdata for the current user from the database, and then get a specific field in the document (in this ex, 'username'). I get the following errors: "The getter 'docs' was called on null. Receiver: null. Tried calling: docs" , & "Class 'DocumentSnapshot' has no instance getter 'docs'. Receiver: Instance of 'DocumentSnapshot'. Tried calling: docs". What improvements can I make? 

Future getCurrentUserData() async{
    final String userId = user.uid;
    final userData = await FirebaseFirestore.instance.collection('users').doc(userId).get();
    return userData;
  }
Widget build(BuildContext context) {
   return FutureBuilder(
      future: getCurrentUserData(),
      builder: (context,  snapshot) {
        final postDocs = snapshot.data.docs;
        return DefaultTabController(
        .....
            title: Text(
                postDocs.data()['username'],)

Suzuki Tomohiro

unread,
Apr 7, 2021, 10:04:36 AM4/7/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
1. When you use Future and FutureBuilder, add subtype, such as Future<String>.


Alvaro Gonzalez Rico

unread,
Apr 7, 2021, 10:34:14 AM4/7/21
to Flutter Development (flutter-dev)
Based on the info and feedback, I have updated my code (see below). I think my error is in what is in bold. On the code itself, there is nothing underlined in red, but when I save/restart/update the app, I get the error: "the method 'data' was called on null. Receiver: null. Tried calling: data()". I do not know why it is not working.

Future<DocumentSnapshot> getCurrentUserData() async{
    final String userId = user.uid;
    final userData = await FirebaseFirestore.instance.collection('users').doc(userId).get();
    return userData;
  }
return FutureBuilder(
      future: getCurrentUserData(),
      builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        final postDocs = snapshot.data;
        return DefaultTabController(
            title: Text(postDocs.data()['username'],)

Suzuki Tomohiro

unread,
Apr 7, 2021, 11:12:07 AM4/7/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)

Alvaro Gonzalez Rico

unread,
Apr 9, 2021, 9:35:05 AM4/9/21
to Flutter Development (flutter-dev)
Hello! Sorry for the delay, but I just updated flutter to v2, and I have to update the majority of my code. Do you have any advice to do the update smoothly? Thanks

Suzuki Tomohiro

unread,
Apr 9, 2021, 9:43:33 AM4/9/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
Advice: Please stop Flutter upgrade and go back to check snapshot status in FutureBuilder.

Alvaro Gonzalez Rico

unread,
Apr 9, 2021, 9:58:00 AM4/9/21
to Flutter Development (flutter-dev)
Hello! What do you mean by "go back to check snapshot status in FutureBuilder"?

Alvaro Gonzalez Rico

unread,
Apr 9, 2021, 9:58:47 AM4/9/21
to Flutter Development (flutter-dev)
It is true, now all my snapshots are underlined in red.

Alvaro Gonzalez Rico

unread,
Apr 9, 2021, 10:27:24 AM4/9/21
to Flutter Development (flutter-dev)
What do you suggest I do regarding the snapshots that are underlined in red?

Suzuki Tomohiro

unread,
Apr 9, 2021, 11:37:39 AM4/9/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
I advised you to check the snapshot status when you use FutureBuilder and I’m waiting for your response.

Alvaro Gonzalez Rico

unread,
Apr 9, 2021, 12:51:56 PM4/9/21
to Flutter Development (flutter-dev)
For some reason, it had a lot of red underlines everywhere in the code (especially under 'snapshot'), but after closing visual code and reopen it, everything seems to work. I have some areas that are deprecated (underlined in blue), likes some buttons, but besides that all seems fine. 
The ONLY thing that gives me an error in the debug console, not in the code itself (even before the flutter upgrade), is regarding the issue we were previously talking about regarding getting the 'username' from firebase. For some reason, I am getting the correct 'username' on the IU, but in the debug console I get the following error: "The method 'data' was called on null. Receiver: null. Tried calling: data()". I'm confused as to why I am getting an error if it seems to work fine in the UI. What do you think?

Suzuki Tomohiro

unread,
Apr 9, 2021, 1:22:54 PM4/9/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
The build function was called twice. First without a data and the second with data.

Alvaro Gonzalez Rico

unread,
Apr 12, 2021, 8:39:05 AM4/12/21
to Flutter Development (flutter-dev)
Hello! Thanks for the feedback. What do you mean the "build function was called twice"? From my understanding, I do not see any of my code repeated.

Suzuki Tomohiro

unread,
Apr 12, 2021, 9:12:10 AM4/12/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
Right. It’s FutureBuilder that calls your code multiple times.

Alvaro Gonzalez Rico

unread,
Apr 13, 2021, 8:13:34 AM4/13/21
to Flutter Development (flutter-dev)
Yes, makes sense. Where in my code do you think it happens (see code below)? Thanks!

class ProfileScreen extends StatelessWidget {
  final user = FirebaseAuth.instance.currentUser;
  
  Future<DocumentSnapshot> getCurrentUserData() async{
    final String userId = user.uid;
    final userData = await FirebaseFirestore.instance.collection('users').doc(userId).get();
    return userData;
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: getCurrentUserData(),
      builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        final postDocs = snapshot.data; 
        return DefaultTabController(
          length: 2,
          child: Scaffold(
            appBar: AppBar(
              title: Text(
                postDocs.data()['username'],

Suzuki Tomohiro

unread,
Apr 13, 2021, 8:24:36 AM4/13/21
to Alvaro Gonzalez Rico, Flutter Development (flutter-dev)
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        final postDocs = snapshot.data; 
        return DefaultTabController(
          length: 2,
          child: Scaffold(
            appBar: AppBar(
              title: Text(
                postDocs.data()['username'],

yash1...@gmail.com

unread,
Apr 14, 2021, 3:11:39 AM4/14/21
to Flutter Development (flutter-dev)
Hey if you want to call it just one time. Then rather than future builder which will keep updating I would suggest go for an another technique.

var userName = "";
initState(){
final getData = getUsername();
super.initState();
}

getUsername() async {
userName = await getCurrentUserDatat();
return;
}

And afterward, use userName in your UI.

Reply all
Reply to author
Forward
0 new messages