Ошибка транзакции Firebase Firestore: невозможно изменить зафиксированный WriteBatch

Я развертываю облачные функции и получаю эту ошибку

Error: Cannot modify a WriteBatch that has been committed.
at WriteBatch.verifyNotCommitted (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/write-batch.js:112:19)
at WriteBatch.update (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/write-batch.js:299:14)
at Transaction.update (/user_code/node_modules/firebase-admin/node_modules/@google-cloud/firestore/build/src/transaction.js:225:33)
at transaction.get.then (/user_code/index.js:22:40)
at process._tickDomainCallback (internal/process/next_tick.js:135:7)

Ниже приведен мой код, я использую транзакцию для обновления и удаления в Firestore.

    const functions = require('firebase-functions');

 const admin = require('firebase-admin');
 admin.initializeApp();
   const firestore = admin.firestore();

  exports.updateUserSize = functions.auth.user().onDelete((user) => {
var userDocRef = firestore.collection("users").where('uid', '==', 
 user.uid).limit(1);

return firestore.runTransaction(function(transaction) {
    return transaction.get(userDocRef).then((snapshot) => {
        snapshot.forEach(userDoc => {
            if (!userDoc.exists) {
                throw "userDoc does not exist!";
            }
            console.info("user_uid: " + userDoc.data().uid + " | instanceDocId: " + userDoc.data().instance);

            var instanceDocRef = firestore.collection("utils").doc(userDoc.data().instance);
            return transaction.get(instanceDocRef).then((snapshot) => {
                console.info("snapshotn: " + snapshot.data().user_size);
                var newUserSize = snapshot.data().user_size - 1;
                transaction.update(instanceDocRef, { user_size: newUserSize });
            });
        });
    });    

}).then(function() {
    console.info("Transaction successfully committed!");
}).catch(function(error) {
    console.info("Transaction failed: ", error);
});
 });

Любая помощь будет высоко оценена.

Пожалуйста, добавьте ВЕСЬ код вашей облачной функции. Людям, которые пытаются вам помочь, важно видеть весь код. Спасибо. Кроме того, можете ли вы указать, какая строка № 22?

Renaud Tarnec 23.02.2019 16:28

Я думаю, ваша проблема связана с тем, что вы несколько раз возвращаете transaction в цикл forEach. Также вы не возвращаете транзакцию при выполнении transaction.update(instanceDocRef, { user_size: newUserSize });.

Renaud Tarnec 23.02.2019 16:31

строка № 22: transaction.update(instanceDocRef, {user_size: newUserSize}); можете ли вы привести пример возврата обновления?

Permadi 23.02.2019 16:36

Рекомендую подробно изучить документацию: firebase.google.com/docs/firestore/manage-data/transactions и firebase.google.com/docs/reference/js/…. С циклом forEach я думаю, что вы не следуете ограничению: «Транзакция состоит из любого количества операций get() последовал любым количеством операций записи, таких как set(), update() или delete()».

Renaud Tarnec 23.02.2019 16:38
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
1 335
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это было решено с помощью цикла for, как упоминал @Renaud Tarnec в комментариях.

I think your problem comes form the fact that you are returning several times the transaction into the forEach loop. Also you don't return the transaction when doing transaction.update(instanceDocRef, { user_size: newUserSize });. I would kindly suggest that you study into detail the documentation: https://firebase.google.com/docs/firestore/manage-data/transactions and https://firebase.google.com/docs/reference/js/firebase.firestore.Transaction. With the forEach loop I think that you are not following the constraint: "A transaction consists of any number of get() operations followed by any number of write operations such as set(), update(), or delete(). "

Другие вопросы по теме