Как избежать ненужных чтений Firestore с Cache - PullRequest
0 голосов
/ 08 октября 2018

У меня есть список данных поездок (большие наборы), упорядоченные по дате.

Существующее поведение

Сначала я сохраню все данные поездок в SqlLite Db.При каждом добавлении новых данных я отправляю уведомление fcm о новых доступных данных и синхронизирую только новые добавленные данные с помощью lut.Таким образом, когда cx открывает приложение, он всегда будет читать данные из моей БД, следовательно, сохраняя read и network операций.

Как могя достигаю того же с Firestore?

Несколько проблем для рассмотрения:

  • Firestore get () всегда сначала пытается получить данные от SERVER, даже если я добавляю CACHE вмой запрос, как я могу синхронизировать только обновленный документ
  • В моем представлении Recyler я хочу, чтобы данные были упорядочены по полю дата не по lut (время последнего изменения)
  • С FireStore Snapshot Listener я не могу запросить такой большой набор записей.

1 Ответ

0 голосов
/ 08 октября 2018

Firestore get () всегда сначала пытается получить данные от SERVER, даже если я добавлю CACHE в свой запрос, как я могу синхронизировать только обновленный документ?

Согласноофициальная документация, касающаяся включения автономных данных :

Для Android и iOS постоянное отключение по умолчанию включено по умолчанию.

Таким образом, для использования автономного сохраненияне нужно вносить («добавлять») какие-либо изменения в ваш код, чтобы иметь возможность использовать и получать доступ к данным Cloud Firestore.

Также в соответствии с официальной документацией по поводу запроса get () method:

По умолчанию get () пытается предоставить по возможности самые последние данные, ожидая данных с сервера, но может вернуть кэшированные данные или потерпит неудачу, если вы находитесь в автономном режимеи сервер не может быть достигнут.Это поведение можно изменить с помощью параметра Source .

Так что это нормальное поведение.Начиная с 2018-06-13 (16.0.0 SDK) теперь можно указывать источник, из которого мы хотим получать данные.Мы можем достичь этого с помощью методов DocumentReference.get (источник) и Query.get (источник) .

Как вы можете видеть, мытеперь можно передавать в качестве аргумента DocumentReference или Query источнику, чтобы мы могли принудительно получить данные с server only, chache only или попытаться выполнить сервер и вернуться к кешу.

Так что теперь возможно что-то подобное:

yourDocRef.get(Source.SERVER).addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
        //Get data from the documentSnapshot object
    }
});

В этом случае мы принудительно извлекаем данные только с сервера.Если вы хотите, чтобы данные извлекались только из кэша, вы должны передать в качестве аргумента метод get(), Source.SERVER.Больше информации здесь .

Если вы хотите получить только updated documents, вы можете просматривать изменения между снимками .Примером из официальной документации будет:

db.collection("cities")
    .whereEqualTo("state", "CA")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot snapshots,
                @Nullable FirebaseFirestoreException e) {
        if (e != null) {
            Log.w(TAG, "listen:error", e);
            return;
        }

        for (DocumentChange dc : snapshots.getDocumentChanges()) {
            switch (dc.getType()) {
            case ADDED:
                Log.d(TAG, "New city: " + dc.getDocument().getData());
                break;
            case MODIFIED:
                Log.d(TAG, "Modified city: " + dc.getDocument().getData());
                break;
            case REMOVED:
                Log.d(TAG, "Removed city: " + dc.getDocument().getData());
                break;
            }
        }

        }
    });

См. Оператор switch для каждого конкретного случая?Второй случай поможет вам получить только обновленные данные.

В моем представлении Recyler я хочу, чтобы данные были упорядочены по дате поля, а не по lut (время последнего изменения)

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

Firestore-root
   |
   --- items (collection)
        |
        --- itemId (document)
             |
             --- date: Oct 08, 2018 at 6:16:58 PM UTC+3
             |
             --- //other properties

Такой запрос поможет вам достичь этого:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionRefference itemsRef = rootRef.collection("items");
Query query = itemsRef.orderBy("date", Query.Direction.ASCENDING);

This также рекомендуется добавлять метку времени в базу данных Cloud Firestore.

С помощью прослушивателя моментальных снимков FireStore я не могу запрашивать такой большой набор записей.

О да, вы можете.Согласно этому ответу , Firebase может эффективно перебирать миллиарды предметов.Этот ответ относится к базе данных Firebase в реальном времени, но к Cloud Firestore применяются те же принципы.

...