Flutter CRUD help

I’ve been working on a little project on flutter since I just started learning it a week ago and I’m just wondering how I could retrieve and use a specific snippet of data from Firebase’s Firestore database.

Here is the code on the relevant files:

database.dart


class DatabaseMethods {

  final String uid;
  DatabaseMethods({this.uid});

  final CollectionReference users = Firestore.instance.collection("users");


  Future<void> updateUserData(String name, String handle) async {
    print(uid);
    return await users.document(uid).updateData({
      'name' : name,
      'handle' : handle,
    });
  }

  Future<void> updateSpecificUserData(String uid, String name, String handle) async {
    print(uid);
    return await users.document(uid).updateData({
      'name' : name,
      'handle' : handle,
    });
  }
  Future<String> getSpecificUserData(String uid) async {
    String user = '';
    await Firestore.instance
        .collection('users')
        .document(uid)
        .get()
        .then((DocumentSnapshot ds) {
          user = ds["name"];
    });
    return user;
  }
 Future<String> retrieveData(String uid) async {
    DocumentSnapshot snap = await users.document(uid).get();
    Map<String, String> map = snap.data;
    String handle = map['name'];
    return handle;
  }
//
  uploadUserInfo(userMap) {
    Firestore.instance.collection("users").add(userMap);
  }


  // user data from snapshot
  Stream<QuerySnapshot> get userInfo {
    return users.snapshots();
  }

}

profile.dart

import 'package:flutter/material.dart';
import 'package:plannus/messages/database.dart';
import 'package:plannus/models/user.dart';
import 'package:plannus/services/auth.dart';
import 'package:provider/provider.dart';

class Profile extends StatefulWidget {
  @override
  _ProfileState createState() => _ProfileState();
}

class _ProfileState extends State<Profile> {

  final AuthService auth = AuthService();
  final formKey = GlobalKey<FormState>(); // 'id' of form
  bool loading = false;
  // text field state
  String name = '';
  String password = '';
  String handle = '';
  String error = '';

  DatabaseMethods databaseMethods = new DatabaseMethods();
  QuerySnapshot currentUser;


  @override
  Widget build(BuildContext context) {

    User user = Provider.of<User>(context);
    String handle = '';
    print(user.uid);
    Future<String> str = databaseMethods.retrieveData(user.uid);
    str.then((value) => {
      handle = value
    });
    print(handle);
      return new Scaffold(
//          appBar: AppBar(
//            title:
//          ),
          body: Container(
            padding: EdgeInsets.symmetric(vertical: 20, horizontal: 50),
            child: Form(
              key: formKey, // keep track of form and its state
              child : Column (
                children: <Widget>[
                  Image.asset('assets/profilepicture.png', height: 300, width: 300),
                  SizedBox(height: 20),
                  TextFormField(
                    decoration: InputDecoration(
                      hintText: 'Name',
                      icon: Icon(Icons.person_outline, color: Colors.blue),
                      fillColor: Colors.white,
                      filled: true,
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.grey[300], width: 2),
                      ),
                        focusedBorder: OutlineInputBorder(
                        borderSide: BorderSide(color: Colors.blue, width: 2),
                    )
                    ),
                    validator: (val) => val.isEmpty ? 'Enter your name' : null,
                    onChanged: (val) {
                      setState(() => name = val);
                    },
                  ),
                  SizedBox(height: 20),
                  TextFormField(
                    decoration: InputDecoration(
                        hintText: 'Handle',
                        icon: Icon(Icons.alternate_email, color: Colors.blue),
                        fillColor: Colors.white,
                        filled: true,
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.grey[300], width: 2),
                        ),
                        focusedBorder: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.blue, width: 2),
                        )
                    ),
                    obscureText: false,
                    validator: (val) => val[0] != '@' ? 'Handle starts with @!' : null,
                    onChanged: (val) {
                      setState(() => handle = val);
                    },
                  ),
                  SizedBox(height: 20),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget> [
                      RaisedButton(
                        color: Colors.blueAccent,
                        child: Text(
                          'Update',
                          style: TextStyle(color: Colors.white),
                        ),
                        onPressed: () async {
                          if(formKey.currentState.validate()) {
                            print(user.uid);
                            await databaseMethods.updateSpecificUserData(user.uid, name, handle);
                            setState(() {
                              error = 'Update successful!';
                            });
                          }
                        },
                      ),
                    ],
                  ),
                  SizedBox(height: 12),
                  Text(
                    error,
                    style: TextStyle(color: Colors.black, fontSize: 16),
                  )
                ],
              ),
            ),
          ),
      );
    }
}

My code can be real messy (for which I apologise because I have been stuck on this for a quite long time and have been rigorously attempting various methods to extract the data out).

Ultimately, my main objective is to get the value from my data stored in firebase and then to dynamically display it on my appbar.

My firebase database collection is named ‘users’ and carries only data { name: “…”, handle: “…”}.

Thanks for bearing with my long post.

Hello and welcome,
I’ve taken a fast glance at your code to try to answer your specific question about the app bar title.

In DatabaseMethods class you have a getSpecificUserData(String uid) method, which is returning the name of a user given his uid.
But in Profile (profile.dart), you are invoking a databaseMethods.retrieveData(user.uid) method instead, which I couldn’t find implemented in the DatabaseMethods class.

Also I’m not sure if you want to display the name or the handle. Let’s say it is the name (for the above returned value).

I’m just guessing here, maybe you could have the app bar title updated with the user’s name with something like:

Future<String> str = databaseMethods.getSpecificUserData(user.uid);
str.then((value) => {
    setState(() {
        name = value;
    });
});

return new Scaffold(
    appBar: AppBar(title: name),
    body: ...

Beware that in this way the handle string will not be assigned the value anymore, in case you can still add the assignment if you still need it below.

I hope this helps, and I didn’t miss something reading your code, or misunderstood your question.

Oops sorry! I wanted to display the user’s handle on top of the profile image with the appbar of the scaffold.

I have updated the database.dart with the relevant retrieveData method.

I did try your method in my build method, but it remains an empty string.

I see, sorry, I didn’t test it, just was a quick idea about using setState. I’d like to help more, but in the next days I’ll be too busy with relocation :sweat:. Hope you can solve it.