Flutter实时数据库交互插件firebase_database的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter实时数据库交互插件firebase_database的使用

简介

firebase_database 是一个Flutter插件,用于使用 Firebase Realtime Database API。要了解更多关于 Firebase Realtime Database 的信息,请访问 Firebase官网

pub package

入门指南

要开始使用 Flutter 的 Firebase Realtime Database,请参阅 官方文档

使用方法

详细的使用说明可以参考 Firebase Realtime Database Usage 文档

问题与反馈

如果您遇到了特定于 FlutterFire 的问题、错误或功能请求,请在我们的 issue tracker 中提交。非特定于 FlutterFire 的插件问题可以在 Flutter issue tracker 中提交。

如需贡献代码修改,请查看我们的 贡献指南,并提交 pull request


示例代码

下面是一个完整的示例应用,展示了如何使用 firebase_database 插件来实现与 Firebase Realtime Database 的交互。

示例代码:main.dart

// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb;
import 'package:flutter/material.dart';

import 'firebase_options.dart';

// Change to false to use live database instance.
const USE_DATABASE_EMULATOR = true;
// The port we've set the Firebase Database emulator to run on via the
// `firebase.json` configuration file.
const emulatorPort = 9000;
// Android device emulators consider localhost of the host machine as 10.0.2.2
// so let's use that if running on Android.
final emulatorHost =
    (!kIsWeb && defaultTargetPlatform == TargetPlatform.android)
        ? '10.0.2.2'
        : 'localhost';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  if (USE_DATABASE_EMULATOR) {
    FirebaseDatabase.instance.useDatabaseEmulator(emulatorHost, emulatorPort);
  }

  runApp(
    const MaterialApp(
      title: 'Flutter Database Example',
      home: MyHomePage(),
    ),
  );
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  late DatabaseReference _counterRef;
  late DatabaseReference _messagesRef;
  late StreamSubscription<DatabaseEvent> _counterSubscription;
  late StreamSubscription<DatabaseEvent> _messagesSubscription;
  bool _anchorToBottom = false;

  String _kTestKey = 'Hello';
  String _kTestValue = 'world!';
  FirebaseException? _error;
  bool initialized = false;

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

  Future<void> init() async {
    _counterRef = FirebaseDatabase.instance.ref('counter');

    final database = FirebaseDatabase.instance;

    _messagesRef = database.ref('messages');

    database.setLoggingEnabled(false);

    if (!kIsWeb) {
      database.setPersistenceEnabled(true);
      database.setPersistenceCacheSizeBytes(10000000);
    }

    if (!kIsWeb) {
      await _counterRef.keepSynced(true);
    }

    setState(() {
      initialized = true;
    });

    try {
      final counterSnapshot = await _counterRef.get();

      print(
        'Connected to directly configured database and read '
        '${counterSnapshot.value}',
      );
    } catch (err) {
      print(err);
    }

    _counterSubscription = _counterRef.onValue.listen(
      (DatabaseEvent event) {
        setState(() {
          _error = null;
          _counter = (event.snapshot.value ?? 0) as int;
        });
      },
      onError: (Object o) {
        final error = o as FirebaseException;
        setState(() {
          _error = error;
        });
      },
    );

    final messagesQuery = _messagesRef.limitToLast(10);

    _messagesSubscription = messagesQuery.onChildAdded.listen(
      (DatabaseEvent event) {
        print('Child added: ${event.snapshot.value}');
      },
      onError: (Object o) {
        final error = o as FirebaseException;
        print('Error: ${error.code} ${error.message}');
      },
    );
  }

  @override
  void dispose() {
    super.dispose();
    _messagesSubscription.cancel();
    _counterSubscription.cancel();
  }

  Future<void> _increment() async {
    await _counterRef.set(ServerValue.increment(1));

    await _messagesRef
        .push()
        .set(<String, String>{_kTestKey: '$_kTestValue $_counter'});
  }

  Future<void> _incrementAsTransaction() async {
    try {
      final transactionResult = await _counterRef.runTransaction((mutableData) {
        return Transaction.success((mutableData as int? ?? 0) + 1);
      });

      if (transactionResult.committed) {
        final newMessageRef = _messagesRef.push();
        await newMessageRef.set(<String, String>{
          _kTestKey: '$_kTestValue ${transactionResult.snapshot.value}',
        });
      }
    } on FirebaseException catch (e) {
      print(e.message);
    }
  }

  Future<void> _deleteMessage(DataSnapshot snapshot) async {
    final messageRef = _messagesRef.child(snapshot.key!);
    await messageRef.remove();
  }

  void _setAnchorToBottom(bool? value) {
    if (value == null) {
      return;
    }

    setState(() {
      _anchorToBottom = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (!initialized) return Container();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Database Example'),
      ),
      body: Column(
        children: [
          Flexible(
            child: Center(
              child: _error == null
                  ? Text(
                      'Button tapped $_counter time${_counter == 1 ? '' : 's'}.\n\n'
                      'This includes all devices, ever.',
                    )
                  : Text(
                      'Error retrieving button tap count:\n${_error!.message}',
                    ),
            ),
          ),
          ElevatedButton(
            onPressed: _incrementAsTransaction,
            child: const Text('Increment as transaction'),
          ),
          ListTile(
            leading: Checkbox(
              onChanged: _setAnchorToBottom,
              value: _anchorToBottom,
            ),
            title: const Text('Anchor to bottom'),
          ),
          Flexible(
            child: FirebaseAnimatedList(
              key: ValueKey<bool>(_anchorToBottom),
              query: _messagesRef,
              reverse: _anchorToBottom,
              itemBuilder: (context, snapshot, animation, index) {
                return SizeTransition(
                  sizeFactor: animation,
                  child: ListTile(
                    trailing: IconButton(
                      onPressed: () => _deleteMessage(snapshot),
                      icon: const Icon(Icons.delete),
                    ),
                    title: Text('$index: ${snapshot.value}'),
                  ),
                );
              },
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

关键点解释

  1. 初始化 Firebase:

    • 使用 Firebase.initializeApp() 初始化 Firebase。
    • 如果启用了数据库模拟器 (USE_DATABASE_EMULATOR),则配置模拟器连接。
  2. 设置数据库引用:

    • 创建对 countermessages 节点的引用。
    • 设置持久化和缓存大小(仅限非 Web 平台)。
    • 启用数据同步(仅限非 Web 平台)。
  3. 监听数据库变化:

    • 使用 onValue 监听 counter 节点的变化。
    • 使用 onChildAdded 监听 messages 节点的新子节点添加。
  4. 操作数据库:

    • 实现 _increment 方法,通过 ServerValue.increment 增加计数器,并向 messages 节点添加新消息。
    • 实现 _incrementAsTransaction 方法,通过事务机制增加计数器,并添加新消息。
    • 实现 _deleteMessage 方法,删除指定的消息。
  5. UI 组件:

    • 使用 FirebaseAnimatedList 显示 messages 节点的数据,并允许用户删除消息。
    • 提供按钮和复选框来控制 UI 行为。

这个示例展示了如何在 Flutter 应用中使用 firebase_database 插件进行实时数据库交互,包括读取、写入、监听和删除数据等常见操作。

希望这个示例能帮助你更好地理解和使用 firebase_database 插件!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter实时数据库交互插件firebase_database的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter实时数据库交互插件firebase_database的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用firebase_database插件实现实时数据库交互的代码案例。这个案例将展示如何连接到Firebase实时数据库,读取数据,监听数据变化,以及写入数据。

首先,确保你已经在pubspec.yaml文件中添加了firebase_database依赖:

dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^1.10.0  # 确保也添加了firebase_core
  firebase_database: ^9.0.0  # 使用最新版本

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,按照以下步骤进行配置和使用:

  1. 初始化Firebase

在你的应用的主入口文件(通常是main.dart)中,初始化Firebase。

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_database/firebase_database.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
  1. 创建数据库引用

在你的主要逻辑文件中,创建一个Firebase数据库的引用。

class _MyHomePageState extends State<MyHomePage> {
  final DatabaseReference _databaseReference = FirebaseDatabase.instance.reference();

  // 用于存储从数据库中读取的数据
  String? _value;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Firebase Database Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Value from Firebase: $_value',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _writeValueToDatabase,
              child: Text('Write Value'),
            ),
          ],
        ),
      ),
    );
  }

  void _writeValueToDatabase() {
    _databaseReference.child('myKey').set({
      'value': 'Hello, Firebase!',
    });
  }

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

  void _listenForValue() {
    _databaseReference.child('myKey').onValue.listen((event) {
      if (event.snapshot.value != null) {
        setState(() {
          _value = event.snapshot.value['value'] as String?;
        });
      }
    });
  }
}
  1. 构建UI

在你的UI文件中,使用上面的逻辑来显示从Firebase读取的数据,并提供一个按钮来写入数据。

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 已在上面的代码段中定义
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

这个示例展示了如何:

  • 初始化Firebase。
  • 创建一个Firebase数据库的引用。
  • 监听特定数据的变化,并在UI中更新显示的数据。
  • 向Firebase数据库写入数据。

确保你的Firebase项目已正确配置,并且你已经在Firebase控制台中启用了实时数据库。此外,确保你的应用具有访问数据库的权限。

这个代码案例提供了一个基本的框架,你可以根据需要进行扩展和修改。

回到顶部