简体   繁体   中英

Flutter /Firebase - Accessing the realtime database

In my flutter project, I need to access the realtime database to get the name of the user when they create a post. This is the code I'm working with:

class PostScreen extends StatelessWidget {
  static const String idScreen = 'post';
  final String name1 = FirebaseDatabase.instance
      .reference()
      .child('users')
      .child(FirebaseAuth.instance.currentUser.uid)
      .child('name1')
      .toString();
  final String name2 = FirebaseDatabase.instance
      .reference()
      .child('users')
      .child(FirebaseAuth.instance.currentUser.uid)
      .child('name2')
      .toString();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FlatButton(
        child: Text('Create Post'),
        onPressed: () {
          MainScreen.posts.add(Post(
            name1: name1,
            name2: name2,
          ));
          Navigator.pushNamed(context, MainScreen.idScreen);
        },
      ),
    );
  }
}


class Post extends StatelessWidget {
  String name1 = '';
  String name2 = '';

  Post({@required name1, @required name2});
  @override
  Widget build(BuildContext context) {
    return Card(
      child: Row(
        children: [
          Text(name1),
          Text(" and "),
          Text(name2),
        ],
      ),
    );
  }
}

What happens though is that the name is left blank and just creates a card that says " and ". What could I be doing wrong? Thank you in advance for your help.

Your code doesn't read anything from the database yet. For that to happen you need to call the once() stream, or listen to the onValue or onChild... streams.

I also recommend simplifying your problem before continuing. So instead of reading the data for the current user (which requires that you have a current user), simply write some hard-coded data at a known location in the database and read that first. That should look something like this:

  final DatabaseReference ref = FirebaseDatabase.instance
      .reference()
      .child('test');  

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: ref.onValue,
      builder: (BuildContext context, snapshot) {
        if(snapshot.hasData) => return Text(snapshot.value);
        else if(snapshot.hasError) => return Text("Error");
        else return Text("No data (yet)");
      }
    );
  }

There may be syntax errors in this code, so treat it as an example of an approach instead of a copy/paste solution please. If you find any of such errors, please try to solve them on your own - and edit the answer with any fixes.

Also see:

You should be able to do something like this:

DatabaseReference myRef = FirebaseDatabase.instance
  .reference()
  .child('users')
  .child(FirebaseAuth.instance.currentUser.uid)
  .child('name1');
 
StreamBuilder(
 stream: myRef.onValue,
 builder: (context, AsyncSnapshot<Event> snap) {
   if (snap.hasData && !snap.hasError && snap.data.snapshot.value != null) {

   // Handle snapshot data
 
   }
}

If you don't need to continue getting changes from the location you can probably use a future builder and.once() method. Don't have experience with that myself though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM