Firestore NullPointerException при получении firebase.Timestamp.toDate (FieldValue.serverTimestamp обновление медленно обновляется) - PullRequest
0 голосов
/ 06 сентября 2018

После вызова batch.commit или docRef.update (часть вызывает FieldValue.serverTimeStamp для обновления времени отправки), я звоню finish();, чтобы вернуться к предыдущему действию, которое загружает recycleView списка документов, который былобновлено.

Я получаю эту ошибку:

java.lang.NullPointerException: попытка вызвать виртуальный метод 'java.util.Date com.google.firebase.Timestamp.toDate ()' вссылка на нулевой объект`

Я подозреваю, что для вычисления FieldValue.servertimeStamp требуется больше времени и происходит сбой приложения.Однако то же поле, из которого recyclerView извлекает дату и время, уже имеет старое значение.

Я не уверен, почему старое значение не извлекается, а вместо этого выдает ноль.

Q1) Делает ли FieldValue.servertimeStamp поле пустым, пока не будет вычислено новое время / дата?

Я думаю, этот конкретный вызов ожидает ответа отСервер Firebase, таким образом, занимает больше времени, но другие вызовы сначала выполняются локально на устройстве перед обновлением в облаке.Мы ценим некоторые ваши идеи.

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

FirestoreFieldUpdated = false;
Thread myThread = new Thread(
     new Runnable() {
          @Override
          public void run() {
              try {
                     while (!FirestoreFieldUpdated) { //db.updateFields will change FirestorefieldUpdated to true uponSuccess
                           Thread.sleep(1000);
                     }
                  } catch (InterruptedException e) {
                        e.printStackTrace();
                  } finally {
                       finish();
                  }
          }
     }
);
myThread.start();

Q2) Есть ли более элегантный или лучший способ сделать это?Или включить синхронность только для этой конкретной транзакции обновления datetime?

EDIT (добавлено более подробно о том, что я пытаюсь сделать):

Я пытаюсь вызвать этот метод из AddNewOrder.java:

public void updateFields(String actionDateField) {
    Map<String, Object> updates = new HashMap<>();
    updates.put(actionDateField, FieldValue.serverTimestamp());
    updateSubmit.update(updates);
 }

из внешнего класса (AddNewOrder.java):

db = new DatabaseHelper(getApplicationContext());
db.updateFields("OrderDate");
finish();

Finish(); затем передаст меня обратнопредыдущее действие, которое вызывает RecyclerView:

      Query query = mFirestore
            .collection("Org")
            .document(RootCollection)
            .collection("Stores")
            .document(StoreID)
            .collection("Orders")
            .whereGreaterThan("OrderVerified", "")
            .limit(queryLimit);
      mAdapter = new OrdersAdapter(query, FulfilmentActivity.this) {
        @Override
        protected void onError(FirebaseFirestoreException e) {
            // Show a snackbar on errors
            Snackbar.make(findViewById(android.R.id.content),
                    "Error: check logs for info.", Snackbar.LENGTH_LONG).show();
        }
    };

    mAdapter.setQuery(query);
    mOrdersRecycler.setAdapter(mAdapter);


    LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    mOrdersRecycler.setLayoutManager(layoutManager);

В OrdersAdapter.java у меня есть это:

  Orders orders = snapshot.toObject(Orders.class);
  submitDate.setText(FORMAT.format(orders.getOrderDate()));

в public void bind.

Выше приведена строка, котораяПоявилось исключение NullPointerException.

Orders.java:

 public class Orders {
  private Timestamp OrderDate;
  public Orders(Timestamp orderDate) { this.OrderDate = orderDate; }
  public java.util.Date getOrderDate() { return OrderDate.toDate(); }
}

Как это исправить правильно?

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

serverTimeStamp () действительно становится нулевым в кэше до получения ответа от сервера: https://github.com/firebase/firebase-js-sdk/issues/192

См. Это для решения: https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/Document

Я исправил это, добавив следующее:

DocumentSnapshot.ServerTimestampBehavior behavior = ESTIMATE;
Date date = snapshot.getDate("OrderDate", behavior);
0 голосов
/ 06 сентября 2018

Прежде всего, если вы работаете с потоками, чтобы иметь дело с Firestore, вы почти наверняка делаете неправильные вещи. Все API Firestore (фактически, все API Firebase) являются асинхронными и не требуют многопоточности со стороны вашего приложения.

Q1 - в документе, который будет создан с отметкой времени, нет промежуточного нулевого значения. Сервер немедленно интерпретирует маркер временной метки сервера и атомарно записывает объект временной метки в документ.

Q2 - Я не могу точно сказать, что вы пытаетесь сделать с помощью этого кода. Это выход за пределы того, что вы обычно делаете, чтобы написать в Firestore. Если вы хотите знать, изменился ли документ в Firestore, вы присоединяете слушателя к ссылке на этот документ, и слушатель вызывается, когда видится, что документ изменяется. Опять же, в этом случае нет необходимости в многопоточности, потому что все обратные вызовы асинхронны. Пока слушатель добавлен, он будет вызываться.

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