Flutter   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Flutter进阶—Firebase数据库实例大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如果需要使用Firebase实时数据库。首先我们需要为项目配置Firebase,具体配置方法可以在《Flutter实战一Flutter聊天应用(五)》查看,因为我们只需要使用Firebase数据库,所以pubspec.yaml文件内容需要修改一下。

name: talk_casually
description: A new Flutter project.

dependencies: Flutter: sdk: Flutter firebase_database: ^0.0.4

首先我们修改项目的@H_975_5@main.dart文件代码如下。

import 'dart:async';

import 'package:Flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';

void main() {
  runApp(new MyApp());
}

class @H_320_52@myApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter数据库实例',home: new MyHomePage(),);
  }
}

class @H_320_52@myHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<@H_320_52@myHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Flutter数据库实例'),),);
  }
}

打开Firebase控制台,更改Firebase实时数据库的安全规则,选择“Database > 规则”,规则如下所示。

{
  "rules": { "counter":{ ".read": true,".write": true },"messages":{ ".read": true,".write": true } } }

现在我们需要使用DatabaseReference连接到Firebase数据库DatabaseReference表示Firebase数据库中的特定位置,可用于读取或写入数据到该位置。

class _MyHomePageState extends State<MyHomePage> {
  //...
  final DatabaseReference _counterRef = FirebaseDatabase.instance.reference().child('counter');
  final DatabaseReference _messagesRef = FirebaseDatabase.instance.reference().child('messages');
  //...
}

FirebaseDatabase是访问Firebase数据库的入口点,我们可以通过调用FirebaseDatabase.instance获取一个实例,要访问数据库中的位置并读取或写入数据,需要使用referencechild获取指定相对路径中的位置的DatabaseReference,相对路径可以是简单的子key(例如“fred”)或更深的斜线分隔的路径(例如“fred/name/first”)。

我们先增加一个_counter存储按钮点击@L_262_29@。在认情况下,用户的写入操作和缓存数据仅存储在内存中,并在用户重新启动应用程序时丢失。通过将启用持久性设置为true,数据将持续存储在设备(磁盘)存储上,并在应用程序重新启动时再次可用(即使当时没有网络连接)。setPersistenceEnabled能够开启数据库的持久性设置,必须在调用数据库引用方法之前设置此属性,并且每个应用程序只需要调用一次。如果操作成功,则Future将返回true,如果持久性无法设置(可能是已经创建数据库引用),则返回false

class _MyHomePageState extends State<MyHomePage> {
  //...
  int _counter;
  //...
  @override
  void initState() {
    super.initState();
    FirebaseDatabase.instance.setPersistenceEnabled(true);
  }
  //...
}

现在@R_667_9616@程序中,Firebase数据库客户端将缓存同步的数据,并跟踪用户在应用程序运行时发起的所有写入。当网络连接恢复时,它可以无缝地处理间歇性网络连接并重新发送写入操作。认情况下,Firebase数据库客户端将使用高达10MB的磁盘空间来缓存数据。如果缓存增长超过此大小,客户端将开始删除未使用的数据。如果发现应用程序缓存数据太少或太多,可以使用setPersistenceCacheSizeBytes来更改缓存大小。此属性必须在调用数据库引用方法之前设置,并且每个应用程序只需要调用一次。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  void initState() {
    super.initState();
    FirebaseDatabase.instance.setPersistenceEnabled(true);
    FirebaseDatabase.instance.setPersistenceCacheSizeBytes(10000000);
  }
  //...
}

如果操作成功,则Future将返回true,如果该值无法设置,则为false(可能已经创建数据库引用)。需要注意的是,指定的高速缓存大小只是一个近似值,并且磁盘上的大小有时会暂时超过它。该属性不支持小于1MB或大于100MB的缓存大小。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  void initState() {
    super.initState();
    FirebaseDatabase.instance.setPersistenceEnabled(true);
    FirebaseDatabase.instance.setPersistenceCacheSizeBytes(10000000);
    _counterRef.keepSynced(true);
  }
  //...
}

通过在某个位置调用keepSynced(true),即使没有为该位置附加任何监听器,该位置的数据将自动下载并保持同步。另外,当一个位置保持同步时,它不会被从持久磁盘缓存中逐出。

现在我们增加两个StreamSubscription类型的变量,StreamSubscription表示来自Stream的事件的订阅订阅将提供事件给侦听器,并保存用于处理事件的回调。订阅也可以用于取消订阅事件,或者临时暂停Stream中的事件。Stream是异步数据事件的来源,Stream提供了一种接收一系列事件的方式。每个Event都是一个数据事件,也称为流的元素,或者一个错误事件。当流已经发出其所有事件时,一个“完成”事件将通知侦听器已到达结束。我们可以监听流,使其开始生成事件,并设置接收事件的侦听器。当我们侦听时,将收到一个StreamSubscription对象,该对象是提供事件的活动对象,可以用于停止再次监听,或临时暂停订阅的事件。

class _MyHomePageState extends State<MyHomePage> {
  //...
  StreamSubscription<Event> _counterSubscription;
  StreamSubscription<Event> _messagesSubscription;
  //...
}

现在需要在应用程序启动时读取按钮被点击的@L_262_29@。onValue表示当该位置的数据更新时触发。Event里封装了DataSnapshot,也可能是其以前的兄弟的key,通常用于命令快照(即返回一个DataSnapshot)。DataSnapshot包含来自Firebase数据库位置的数据,每当我们读取Firebase数据时,将收到一个DataSnapshotDataSnapshotvalue属性以本机类型返回此数据快照的内容

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  void initState() {
    //...
    _counterSubscription = _counterRef.onValue.listen((Event event) {
      setState(() {
        _counter = event.snapshot.value ?? 0;
      });
    });
  }
  //...
}

上面代码中的双问号操作符意思是取所赋值??左边的,如果左边为null,取所赋值??右边的。应用程序在启动时还应该获取消息列表,还可以打印在控制台上。DatabaseReferencelimitToLast方法会创建一个有限制的查询并将其锚定到窗口的末尾。onChildAdded表示在子数据加入时调用。当我们使用Stream.listenStream上侦听时,会返回一个StreamSubscription对象。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  void initState() {
    //...
    _messagesSubscription =  _messagesRef.limitToLast(10).onChildAdded.listen((Event event) {
          print('子数据增加了: ${event.snapshot.value}');
        });
  }
  //...
}

在资源使用完之后及时关闭一个良好的习惯,StreamSubscriptioncancel方法用于取消订阅,在此调用之后,订阅不再接收事件。流可能需关闭事件源,并在订阅取消后进行清理。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  void dispose() {
    super.dispose();
    _messagesSubscription.cancel();
    _counterSubscription.cancel();
  }
  //...
}

修改build内容,使我们可以看到查看按钮被点击了多少次。

class _MyHomePageState extends State<@H_320_52@myHomePage> {
  //...
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Flutter数据库实例'),body: new column(
        children: <Widget>[
          new Flexible(
            child: new Center(
              child: new Text(
                '按钮点击 $_counter 次,\n\n该统计包括所有的终端!',],);
  }
  //...
}

增加一个_anchorToBottom变量,控制显示消息列表的样式。

class _MyHomePageState extends State<MyHomePage> {
  //...
  bool _anchorToBottom = false;
  //...
}

修改build内容增加一个可选项,按钮如何显示消息列表。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      //...
      body: new column(
        children: <Widget>[
          //...
          new ListTile(
            leading: new checkBox(
              onChanged: (bool value) {
                setState(() {
                  _anchorToBottom = value;
                });
              },value: _anchorToBottom,title: const Text('锚点到底部'),);
  }
  //...
}

现在可以使用FirebaseAnimatedList控件把消息列表显示出来,FirebaseAnimatedList是绑定到查询AnimatedList控件。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      //...
      body: new column(
        children: <Widget>[
          //...
          new Flexible(
            child: new FirebaseAnimatedList(
              key: new ValueKey<bool>(_anchorToBottom),query: _messagesRef,reverse: _anchorToBottom,sort: _anchorToBottom
                  ? (DataSnapshot a,DataSnapshot b) => b.key.compareTo(a.key)
                  : null,itemBuilder: (BuildContext context,DataSnapshot snapshot,Animation<double> animation) {
                return new SizeTransition(
                  sizeFactor: animation,child: new Text(snapshot.value.toString()),);
              },)
        ],);
  }
  //...
}

FirebaseAnimatedList控件中,key属性控制一个控件如何替换树中另一个控件,query属性设置用于填充动画列表的Firebase查询reverse属性设置滚动视图是否在阅读方向滚动,sort属性设置用于在排序列表时比较快照的可选功能itemBuilder属性根据需要调用来构建列表项控件。

我们需要编写一个提交事件,用于将数据上传数据库DatabaseReferenceonce方法侦听单个值事件,然后停止侦听。DatabaseReferenceset方法将值写入具有指定优先级的位置(如果适用),这将覆盖此位置的所有数据。允许写入的数据类型有StringBooleanintdouble、@H_975_5@map和List,写入的效果将立即可见,相应的事件将被触发。如果传递新值为null,表示此位置的所有数据将被删除

class _MyHomePageState extends State<MyHomePage> {
  //...
  String _kTestKey = 'Hello';
  String _kTestValue = 'world!';
  //...
  Future<Null> _increment() async {
    final DataSnapshot snapshot = await _counterRef.once();
    setState(() {
      _counter = (snapshot.value ?? 0) + 1;
    });
    _counterRef.set(_counter);
    _messagesRef.push().set(<String,String>{_kTestKey: '$_kTestValue $_counter'});
  }
  //...
}

DatabaseReferencepush方法使用唯一key生成新的子位置并返一个DatabaseReference。当Firebase数据库位置的子位置是一个列表时,这个方法非常有用。由childByAutoId生成的唯一key以客户端生成的时间戳为前缀,以便生成的列表将按时间顺序排序。

最后我们修改build内容增加一个浮动按钮,并将上面编写的事件作为其点击事件。

class _MyHomePageState extends State<MyHomePage> {
  //...
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Flutter数据库实例'),body: new column(
        //...
      ),floaTingActionButton: new FloaTingActionButton(
        onPressed: _increment,tooltip: '增加',child: new Icon(Icons.add),);
  }
  //...
}

启动应用程序,点击按钮三次,控制台与终端的显示如下:

Flutter进阶—Firebase数据库实例

Flutter进阶—Firebase数据库实例

数据库内容显示如下:

Flutter进阶—Firebase数据库实例

大佬总结

以上是大佬教程为你收集整理的Flutter进阶—Firebase数据库实例全部内容,希望文章能够帮你解决Flutter进阶—Firebase数据库实例所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。