Получение данных из автономной базы данных Firebase (Flutter) - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть приложение, которое проверяет, существует ли только одно значение, когда он попадает на вторую страницу и создает пользовательский интерфейс в соответствии с этой информацией, если я делаю это обычным способом, это требует времени и выдает нулевую ошибку для се c перед построением страницы также мне приходится читать базу данных слишком часто, чем я хочу, так есть ли способ проверить данные только из автономной базы данных при подключении к inte rnet?

Редактировать:

В качестве резюме, у меня есть домашняя страница, и она показывает, что весь список принадлежит пользователю, записанному как избранное с помощью ListView.Builder, и пользователь видит и может удалить их только с этого экрана, единственный способ добавить что-либо в список - это добавить со своей второй страницы, и я проверяю, добавлен элемент или нет при построении, если добавлено изменение формы моей любимой кнопки, и удаляется при нажатии, если кнопка не совпадает, сохраняйте ее в избранном. Вы можете проверить следующие коды (связанные части)

Домашняя страница:

class MyFirstPage extends StatefulWidget {
  MyFirstPage({Key key, this.auth, this.userId, this.logoutCallback, this.user})
      : super(key: key);

  final BaseAuth auth;
  final VoidCallback logoutCallback;
  final String userId;
  final FirebaseUser user;

  static String routeName = "/MyFirstPage";

  @override
  _MyFirstPageState createState() => new _MyFirstPageState();
}

class _MyFirstPageState extends State<MyFirstPage> {
  String userId;
  List<Movies> _moviesList;
  Query _moviesQuery;

  final FirebaseDatabase _database = FirebaseDatabase.instance;
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  StreamSubscription<Event> _onMoviesAddedSubscription;
  StreamSubscription<Event> _onMoviesChangedSubscription;
  AuthStatus authStatus;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
     _moviesList = new List();
    _moviesQuery = _database
        .reference()
        .child("movies")
        .orderByChild("userId")
        .equalTo(widget.userId);
    _onMoviesAddedSubscription = _moviesQuery.onChildAdded.listen(onEntryAdded);
    _onMoviesChangedSubscription =
        _moviesQuery.onChildChanged.listen(onEntryChanged);
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        if (user != null) {
          userId = user?.uid;
        }
        authStatus =
        user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
      });
    });

  }


  void dispose() {
    _onMoviesAddedSubscription.cancel();
    _onMoviesChangedSubscription.cancel();
    super.dispose();
  }

  onEntryChanged(Event event) {
    var oldEntry = _moviesList.singleWhere((entry) {
      return entry.key == event.snapshot.key;
    });

    setState(() {
      _moviesList[_moviesList.indexOf(oldEntry)] =
          Movies.fromSnapshot(event.snapshot);
    });
  }

  onEntryAdded(Event event) {
    setState(() {
      _moviesList.add(Movies.fromSnapshot(event.snapshot));
    });
  }

  signOut() async {
    try {
      await widget.auth.signOut();
      widget.logoutCallback();
    } catch (e) {
      print(e);
    }
  }

  updateMovies(Movies movies) {
    //Toggle completed
    movies.watched = !movies.watched;
    if (movies != null) {
      _database.reference().child("movies").set(movies.toJson());
    }
  }

  deleteMovies(String moviesId, int index) {
    _database.reference().child("movies").child(moviesId).remove().then((_) {
      print("Delete $moviesId successful");
      setState(() {
        _moviesList.removeAt(index);
      });
    });
  }

...
ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: _moviesList.length,
        itemBuilder: (BuildContext context, int index) {...}

Вторая страница:

class MovieDetailPage extends StatefulWidget {
  MovieDetailPage({Key key, this.title, this.auth, this.userId, this.user})
      : super(key: key);

  final BaseAuth auth;
  final String userId;
  final FirebaseUser user;
  static String routeName = "/MovieDetailPage";
  final String title;

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

class _MovieDetailPageState extends State<MovieDetailPage> {
  final GlobalKey<InnerDrawerState> _innerDrawerKey = GlobalKey<InnerDrawerState>();
  final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
  new GlobalKey<RefreshIndicatorState>();

  Future<void> recorded(String idname) async{
    final dbRef = await FirebaseDatabase.instance.reference().child(
        "movies").orderByChild("unique").equalTo(idname).once();
    return dbRef;
  }
  String userId;
  final FirebaseDatabase _database = FirebaseDatabase.instance;
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  List<Movies> _moviesList;
  AuthStatus authStatus;


  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      WidgetsBinding.instance.addPostFrameCallback((_) =>
          getNamePreferences().then(updateName));
    });
    _moviesList = new List();
    widget.auth.getCurrentUser().then((user) {
      if (user != null) {
        userId = user?.uid;
      }});

  }

//I have a FutureBuilder for getting details

FutureBuilder<Payload>(
          future:  getData(_name),
          builder: (context, snapshot) {
            if (snapshot.connectionState != ConnectionState.done && firstRun == true)
              return Center(child: Image.asset("images/dice.gif"));
            if (snapshot.connectionState == ConnectionState.done)
              if (snapshot.hasError)
              {....

// and I have a second FutureBuilder for my FAB because its change according to data
                  floatingActionButton:  FutureBuilder(
                          future: recorded(userId+snapshot.data.imdbId),
                          builder: (context, snapshots) {
                            return Container(
                              width: MediaQuery.of(context).size.width,
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.end,
                                children: <Widget>[
                                  FloatingActionButton(
                                      heroTag: 3,
                                      backgroundColor: Colors.blueGrey.withOpacity(0.4),
                                      onPressed: ()
                                      {
                                        Movies movies = new Movies(snapshot.data.imdbId, snapshot.data.originalTitle, snapshot.data.posterPath, snapshot.data.backdropPath, snapshot.data.releaseDate, snapshot.data.title, snapshot.data.voteAverage, snapshot.data.genres, false, userId, userId+snapshot.data.imdbId);
                                        snapshots.data.value == null ?
                                        _database.reference().child("movies").push().set(movies.toJson())
                                            :
                                        FirebaseDatabase.instance.reference()
                                            .child('movies')
                                            .orderByChild('unique')
                                            .equalTo(userId+snapshot.data.imdbId)
                                            .once()
                                            .then((DataSnapshot snapshot) {
                                          Map<dynamic, dynamic> children = snapshot.value;
                                          children.forEach((key, value) {
                                            FirebaseDatabase.instance.reference()
                                                .child('movies')
                                                .child(key)
                                                .remove();
                                          });
                                        });
                                        setState(() {});
                                      },
                                      child: Icon(snapshots.data.value != null ? Icons.favorite : Icons.favorite_border )
                                  )

                                ],
                              ),
                            );
                          }
                      ),

1 Ответ

1 голос
/ 22 апреля 2020

Я думаю, что вы ищете goOffline метод , который заставляет клиента Firebase отключаться. сервер. После вызова этого метода он попытается выполнить операции чтения из своего локального кэша (либо в памяти, либо на диске) и сохранит очередь ожидающих операций записи для отправки на сервер при повторном подключении (либо при перезапуске приложения, либо когда вы звоните goOnline).

По умолчанию клиент Firebase хранит в памяти кэш всех данных, которые он видел. Вы можете включить сохранение диска , что позволит ему затем записывать этот кэш на диск, чтобы он мог повторно использоваться, если приложение перезапускается, когда вы находитесь в автономном режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...