Очень простая транзакция Firestore не удалась - PullRequest
0 голосов
/ 27 апреля 2018

Я борюсь с супер простой транзакцией. Всегда происходит сбой с сообщением «Транзакция завершилась неудачей при всех повторных попытках», но нет сообщений об ошибках, кроме этого на logcat.

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

Я просто хочу клонировать один документ из одной коллекции в другую. Думайте от "videos" до "favorites" (я знаю, что это может быть сделано вне транзакции, как указывает @Alex, но это только неудачная часть, реальная транзакция длиннее)

private void copy(
    final DocumentReference SOURCEDOCREF, 
    final CollectionReference TARGETCOLREF) {

        Transaction.Function<? extends Void> transaction = new Transaction.Function<Void>() {

            @Nullable
            @Override
            public Void apply(@NonNull Transaction transaction) throws FirebaseFirestoreException {

                DocumentSnapshot doc = transaction.get(SOURCEDOCREF);
                if (doc.exists()) {
                    DocumentReference favoriteRef = TARGETCOLREF.document("FV_" + doc.getId());
                    Map<String, Object> data = doc.getData();
                    transaction.set(favoriteRef, data);
                    return null;

                    // NOTE: This is reached, ie. the source doc exists
                    // the data recovered, and set into the transaction.
                } else
                    throw new FirebaseFirestoreException("Item does not exist", FirebaseFirestoreException.Code.NOT_FOUND);
            }
        };

        setMode(MODE_SPLASH);
        FirebaseFirestore.getInstance().runTransaction(transaction)
                .addOnSuccessListener(
                        (Activity) getContext(),
                        new OnSuccessListener<Object>() {
                            @Override
                            public void onSuccess(Object aVoid) {
                                setMode(MODE_FOLLOW);
                            }
                        })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        hide();
                        DialogHelper.customToast(getContext(), e.getMessage());
                    }
                });
    }

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Согласно документации о транзакциях :

Если транзакция читает документы, а другой клиент изменяет любой из эти документы, Cloud Firestore повторяет транзакцию. Эта особенность обеспечивает выполнение транзакции с использованием актуальных и согласованных данных.

Таким образом, вы можете ожидать, что ваша транзакция будет повторена, если исходный документ был изменен до завершения транзакции.

Вы также можете ожидать сбой транзакции.

Транзакция может завершиться неудачей по следующим причинам:

  • Транзакция содержит операции чтения после операций записи. Операции чтения всегда должны предшествовать любым операциям записи.
  • Транзакция прочитала документ, который был изменен вне транзакции. В этом случае транзакция автоматически запускается снова. Транзакция повторяется конечное число раз.

Неудачная транзакция возвращает ошибку и ничего не записывает в база данных. Вам не нужно откатывать транзакцию; облако Firestore делает это автоматически.

0 голосов
/ 27 апреля 2018

Нет необходимости использовать транзакцию в таком случае. Чтобы скопировать документ из одного места в другое, используйте следующий метод:

public void cloneFirestoreDocument(DocumentReference fromPath, final DocumentReference toPath) {
    fromPath.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task) {
            if (task.isSuccessful()) {
                DocumentSnapshot document = task.getResult();
                if (document != null) {
                    toPath.set(document.getData())
                        .addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Log.d(TAG, "DocumentSnapshot successfully written!");
                            }
                        })
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.w(TAG, "Error writing document", e);
                            }
                        });
                } else {
                    Log.d(TAG, "No such document");
                }
            } else {
                Log.d(TAG, "get failed with ", task.getException());
            }
        }
    });
}

В котором fromPath - это местоположение документа, который вы хотите переместить, а toPath - это локация, в которой вы хотите переместить документ.

Поток выглядит следующим образом:

  1. Get документ из местоположения fromPath.
  2. Write документ до toPath местоположения.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...