2016-04-22 1 views
1

Это довольно странная вещь, и ее трудно воспроизвести. Не лучшее состояние сообщения об ошибке, прошу прощения.Пожарные операции возвращаются несколько раз намного позже?

Я использую .transaction(), чтобы записать значение в местоположение в Firebase. Вот некоторые псевдо-код:

var ref = firebase.child('/path/to/location'); 

var storeSafely = function(val) { 
    ref.transaction(
    function updateFunc(currentData) { 
     console.log('Attempting update: ' + JSON.stringify(val)); 

     if (currentData) return; 

     return val; 
    }, 
    function onTransactionCompleteFunc(err, isCommitted, snap) { 
     if (err) { 
     console.log('Error in onTransactionCompleteFunc: ' + JSON.stringify(err)); 
     return; 
     } 

     if (! isCommitted) { 
     console.log('Not committed'); 
     return; 
     } 

     ref.onDisconnect().remove(); 
     doSomeStuff(); 
    }); 
}; 

var doSomeStuff = function() { 
    // Things get done, time passes. 

    console.log('Cleaning up'); 
    ref.onDisconnect().cancel(); 
    ref.set(
    null, 
    function onSetCompleteFunc(err) { 
     if (err) { 
     console.log('Error in onSetCompleteFunc: ' + JSON.stringify(err)); 
     } 
    }); 
}; 

storeSafely(1); 
// later... 
storeSafely(2); 
// even later... 
storeSafely(3); 

Я эффективно использовать Firebase транзакции в качестве своего рода блокировки мьютекса:

  • магазин значение в месте с помощью транзакции.

  • Установите onDisconnect для определения местоположения, чтобы удалить значение, если мое приложение замирает во время работы.

  • Сделайте некоторые вещи.

  • Удалите onDisconnect для местоположения, потому что я покончил с этим.

  • Удалить значение по месту.

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

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

Attempting update 1 
Attempting update 2 
Attempting update 3 

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

Я пропустил что-то действительно важное здесь о том, как закончить транзакцию?

(Примечание.. Я первоначально отправил это в Firebase группы Google, но в конце концов напомнил, что вопросы кода должны идти на Stack Overflow Извиняюсь за кросс-постинг)

ответ

0

Просто догадка , но мне интересно, вызывается ли ваша функция updateFunc() с null, когда ваше приложение получает ошибки, связанные с разрешением, из Firebase. (Если это так, я могу поверить, что это часть их поддержки «Offline Writes».)

В любом случае, вы должны обрабатывать null в качестве возможного состояния. Saving Transactional Data говорит:

transaction() будет вызываться несколько раз и должны быть в состоянии обрабатывать null данные. Даже если в вашей базе данных есть существующие данные, она может не локально кэшироваться при выполнении функции транзакции .

Я не знаю тонкостей сделки mechansim Firebase, но я хотел бы попробовать изменить свой .set(null), чтобы установить значение 0 вместо этого, изменить ваш .remove() также установить значение с .set(0), и изменить свою линию в updateFunc() чтобы:

if (currentData === null || currentData) return; 

к сожалению, это предполагает, что '/path/to/location' первоначально установлен на 0 в какой-то момент. Если это проблема, возможно, вы можете обмануть null против undefined. Например, было бы неплохо, если бы Firebase использовал один из них для несуществующих данных, а другой, когда он отключен.