为什么 Firebase 实时数据库的数据在控制台中显示为空? [英] Why is the Firebase Realtime Database's data appearing as null in the console?

查看:21
本文介绍了为什么 Firebase 实时数据库的数据在控制台中显示为空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个简单的应用程序,该应用程序将帖子添加到 firebase 实时数据库并在 flutter 中的列表视图上显示它们,但是当我发布"时它到数据库,在 firebase 控制台上,数据值不断显示为空.有谁知道出了什么问题?

I am trying to create a simple app that adds posts to a firebase realtime database and shows them on a listview in flutter, but when I "post" it to the database, on the firebase console, the data value constantly appears as null. does anyone know what is wrong?

这是我的一些代码 -

post.dart

class Post {
  Image coverImg;
  File audioFile;
  String body;
  String author;
  Set usersLiked = {};
  DatabaseReference _id;

  Post(this.body, this.author);

  void likePost(User user) {
    if (this.usersLiked.contains(user.uid)) {
      this.usersLiked.remove(user.uid);
    } else {
      this.usersLiked.add(user.uid);
    }
  }

  void update() {
    updatePost(this, this._id);
  }

  void setId(DatabaseReference id) {
    this._id = id;
  }

  Map<String, dynamic> toJson() {
    return {
      'body': this.body,
      'author': this.author,
      'usersLiked': this.usersLiked.toList()
    };
  }
}

Post createPost(record) {
  Map<String, dynamic> attributes = {
    'author': '',
    'usersLiked': [],
    'body': ''
  };

  record.forEach((key, value) => {attributes[key] = value});

  Post post = new Post(attributes['body'], attributes['author']);
  post.usersLiked = new Set.from(attributes['usersLiked']);
  return post;
}

class PostList extends StatefulWidget {
  final List<Post> listItems;
  final User user;
  PostList(this.listItems, this.user);

  @override
  _PostListState createState() => _PostListState();
}

class _PostListState extends State<PostList> {
  void like(Function callBack) {
    this.setState(() {
      callBack();
    });
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: this.widget.listItems.length,
      itemBuilder: (context, index) {
        var post = this.widget.listItems[index];

        return Card(
            elevation: 7.0,
            color: Colors.white,
            child: Column(
              children: [
                Row(
                  children: [
                    IconButton(
                      icon: Icon(
                        Icons.play_circle_outline,
                        color: Colors.black,
                        size: 30,
                      ),
                      onPressed: () {},
                    ),
                    Expanded(
                      child: ListTile(
                        title: Text(post.body,
                            style: TextStyle(
                                fontWeight: FontWeight.w600,
                                color: Colors.black)),
                        subtitle: Text(post.author,
                            style: TextStyle(color: Colors.black)),
                      ),
                    ),
                    Expanded(
                        child: Row(
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: [
                        Text(post.usersLiked.length.toString(),
                            style: TextStyle(
                                color: Colors.black,
                                fontWeight: FontWeight.w600)),
                        IconButton(
                          icon: Icon(
                            Icons.thumb_up,
                            color: post.usersLiked.contains(widget.user.uid)
                                ? Colors.blue
                                : Colors.black,
                          ),
                          onPressed: () =>
                              this.like(() => post.likePost(widget.user)),
                        )
                      ],
                    ))
                  ],
                )
              ],
            ));
      },
    );
  }
}

database.dart

final databaseReference = FirebaseDatabase.instance.reference();

DatabaseReference savePost(Post post) {
  var id = databaseReference.child('posts/').push();
  id.set(post.toJson());
  return id;
}

void updatePost(Post post, DatabaseReference id) {
  id.update(post.toJson());
}

Future<List<Post>> getAllPosts() async {
  DataSnapshot dataSnapshot = await databaseReference.child('posts/').once();
  List<Post> posts = [];
  if (dataSnapshot.value != null) {
    dataSnapshot.value.forEach((key, value) {
      Post post = createPost(value);
      post.setId(databaseReference.child('posts/' + key));
      posts.add(post);
    });
  }
  return posts;
}

home.dart

class UserInfoScreen extends StatefulWidget {
  const UserInfoScreen({Key key, User user})
      : _user = user,
        super(key: key);

  final User _user;

  @override
  _UserInfoScreenState createState() => _UserInfoScreenState();
}

class _UserInfoScreenState extends State<UserInfoScreen> {
  User _user;
  bool _isSigningOut = false;
  List<Post> posts = [];

  void newPost(String text) {
    var post = new Post(text, widget._user.displayName);
    post.setId(savePost(post));
    this.setState(() {
      posts.add(post);
    });
  }

  void updatePosts() {
    getAllPosts().then((posts) => {
          this.setState(() {
            this.posts = posts;
          })
        });
  }

  Route _routeToSignInScreen() {
    return PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) => SignInScreen(),
      transitionsBuilder: (context, animation, secondaryAnimation, child) {
        var begin = Offset(-1.0, 0.0);
        var end = Offset.zero;
        var curve = Curves.ease;

        var tween =
            Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

        return SlideTransition(
          position: animation.drive(tween),
          child: child,
        );
      },
    );
  }

  @override
  void initState() {
    _user = widget._user;

    // HOME PAGE

    pageList.add(Scaffold(
      backgroundColor: Colors.white,
      body: Column(children: [
        Expanded(
          child: PostList(this.posts, _user),
        ),
      ]),
    ));

    pageList.add(Test1());

    pageList.add(Scaffold(
      backgroundColor: Colors.white,
      body: Column(
        children: [
          TextInputWidget(this.newPost, "Title:"),
        ],
      ),
    ));

    pageList.add(Test3());

    // ACCOUNT PAGE

    pageList.add(
      Scaffold(
        backgroundColor: Colors.white,
        body: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(),
            _user.photoURL != null
                ? ClipOval(
                    child: Material(
                      color: Colors.grey.withOpacity(0.3),
                      child: Image.network(
                        _user.photoURL,
                        fit: BoxFit.fitHeight,
                      ),
                    ),
                  )
                : ClipOval(
                    child: Material(
                      color: Colors.grey.withOpacity(0.3),
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: Icon(
                          Icons.person,
                          size: 60,
                          color: Colors.black,
                        ),
                      ),
                    ),
                  ),
            SizedBox(height: 16.0),
            Text(
              '${_user.displayName}',
              style: TextStyle(
                  color: Colors.black,
                  fontSize: 26,
                  fontWeight: FontWeight.w700),
            ),
            SizedBox(height: 8.0),
            Text(
              ' ${_user.email} ',
              style: TextStyle(
                color: Colors.black,
                fontSize: 20,
                letterSpacing: 0.5,
              ),
            ),
            SizedBox(height: 60.0),
            _isSigningOut
                ? CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
                  )
                : ElevatedButton(
                    style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.all(
                        Colors.redAccent,
                      ),
                      shape: MaterialStateProperty.all(
                        RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10),
                        ),
                      ),
                    ),
                    onPressed: () async {
                      setState(() {
                        _isSigningOut = true;
                      });
                      await Authentication.signOut(context: context);
                      setState(() {
                        _isSigningOut = false;
                      });
                      Navigator.of(context)
                          .pushReplacement(_routeToSignInScreen());
                    },
                    child: Padding(
                      padding: EdgeInsets.only(top: 8.0, bottom: 8.0),
                      child: Text(
                        'Logout',
                        style: TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.w500,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
          ],
        ),
      ),
    );

    super.initState();
    updatePosts();
  }

  @override
  List<Widget> pageList = List<Widget>();
  int _currentIndex = 0;

  void onTabTapped(int index) {
    setState(() {
      _currentIndex = index;
    });
  }

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0.0,
        backgroundColor: Colors.white,
        title: Text(
          'SoundFX',
          style: TextStyle(color: Colors.black),
        ),
        centerTitle: true,
      ),
      body: IndexedStack(
        index: _currentIndex,
        children: pageList,
      ),
      bottomNavigationBar: BottomNavigationBar(
        unselectedItemColor: Colors.grey,
        selectedItemColor: Colors.blue,
        backgroundColor: Colors.white,
        elevation: 19.0,
        onTap: onTabTapped,
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.fixed,
        items: [
          BottomNavigationBarItem(
              icon: new Icon(Icons.home),
              title: Container(
                height: 1.0,
              )),
          BottomNavigationBarItem(
              icon: new Icon(Icons.search),
              title: Container(
                height: 1.0,
              )),
          BottomNavigationBarItem(
              icon: new Icon(
                Icons.add_circle,
                size: 40,
              ),
              title: Container(
                height: 1.0,
              )),
          BottomNavigationBarItem(
              icon: new Icon(Icons.videocam),
              title: Container(
                height: 1.0,
              )),
          BottomNavigationBarItem(
              icon: Icon(Icons.account_circle),
              title: Container(
                height: 1.0,
              )),
        ],
      ),
    );
  }
}




class Test1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
    );
  }
}

class Test2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
    );
  }
}

class Test3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
    );
  }
}

text-input.dart

class TextInputWidget extends StatefulWidget {
  final Function(String) callback;
  String label;

  TextInputWidget(this.callback, this.label);

  @override
  _TextInputWidgetState createState() => _TextInputWidgetState();
}

class _TextInputWidgetState extends State<TextInputWidget> {
  final controller = TextEditingController();

  @override
  void dispose() {
    super.dispose();

    controller.dispose();
  }

  void click() {
    widget.callback(controller.text);
    FocusScope.of(context).unfocus();
    controller.clear();
  }

  void pickFiles() async {
    FilePickerResult result =
        await FilePicker.platform.pickFiles(type: FileType.any);

    File file = File(result.files.first.path);
    print(file);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 400,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Expanded(
            child: Container(
                padding: EdgeInsets.all(20.0),
                child: TextField(
                    controller: this.controller,
                    decoration: InputDecoration(
                      labelText: this.widget.label,
                    ))),
          ),
          Container(
            child: ElevatedButton(onPressed: this.click, child: Text('Post')),
          ),
          Container(
            child:
                ElevatedButton(onPressed: this.pickFiles, child: Text('test')),
          )
        ],
      ),
    );
  }
}

PS:另外,请注意,有些函数和类没有使用或基本没用,有些名称很愚蠢,但如果它们与问题无关,请不要评论,因为这些只是对我添加到应用程序中的功能进行一些测试.

PS: Also, note that some of the functions and classes are unused or basically useless, and some of the names are very stupid, but please do not comment on those if they are not related to the question, as those are just for some tests for features for me to add into the application.

另外,请注意我遵循了本教程 - https://www.youtube.com/playlist?list=PLzMcBGfZo4-knQWGK2IC49Q_5AnQrFpzv

Also, note that i followed this tutorial - https://www.youtube.com/playlist?list=PLzMcBGfZo4-knQWGK2IC49Q_5AnQrFpzv

推荐答案

firebaser here

很可能 Firebase SDK 无法从其配置文件中读取数据库的 URL,因为您的数据库托管在默认(美国)区域之外.

Most likely the Firebase SDK is unable to read the URL of the database from its config file, because your database is hosted outside of the default (US) region.

如果这确实是原因,您应该在代码中指定数据库 URL.通过在代码中指定它,SDK 应该能够连接到数据库实例,无论它托管在哪个区域.

If that is indeed the cause, you should specify the database URL in your code. By specifying it in your code, the SDK should able to connect to the database instance no matter what region it is hosted in.

这意味着您应该使用

FirebaseDatabase("your database URL").reference()
// Or
FirebaseDatabase(databaseURL: "your database URL").reference()

代替

FirebaseDatabase.instance.reference()

记录在此处:

要获取对 us-central1 默认 dstabase 以外的数据库的引用,您必须将数据库 URL 传递给 getInstance()(或 Kotlin+KTX database()).对于 us-central1 默认数据库,可以不带参数调用 getInstance()(或数据库).

To get a reference to a database other than a us-central1 default dstabase, you must pass the database URL to getInstance() (or Kotlin+KTX database()) . For a us-central1 default database, you can call getInstance() (or database) without arguments.

所以,虽然这个记录的,但它非常容易被忽视.我正在与我们的团队核实是否可以采取一些措施来使这个配置问题更加明显.

So while this is documented, it is incredibly easy to overlook. I'm checking with our team if there's something we can do to make this configuration problem more obvious.

这篇关于为什么 Firebase 实时数据库的数据在控制台中显示为空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆