1

In my project app I use Firebase Storage and Database simultaneously. I would like to use transactions concept, however I have never used it before so it's not obvious for me. Users are allowed to upload a file to the server. I track these uploads in database (assigning url's of the uploaded file to the user). So I perform 2 actions at the same time:

  • uploading the file

  • updating database

I wanna be sure that if any of those actions fails, none is performed (e.g. Internet connection is down). I need some tips on how to handle exceptions like the one mentioned before and how to implement it in appropriate way as it is crashing at the moment. Here is the code I have:

newRef.runTransactionBlock({ (currentData: MutableData) -> 
TransactionResult in
 let uploadTask = ref.putData(contents as Data, metadata: 
  self.myMetadata, completion: { (metadata, error) in
    if error != nil {
        ...
    }
    DataService.instance.usersRef.observeSingleEvent(of: .value) { 
    (snapshot: DataSnapshot) in
        ...
     _ = DataService.instance.usersRef.child("\
     (key)/profile/myURLS").updateChildValues([ strEncoded as! 
     AnyHashable : downloadURL])
    }
 }
 return TransactionResult.success(withValue: currentData)
})
{ (error, committed, snapshot) in
 if let error = error {
   print(error.localizedDescription)
 }
}

Thanks in advance!

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
misi06
  • 259
  • 1
  • 8
  • 16

1 Answers1

0

Transactions only run within the context of the database where the transaction is started. The all-or-none behavior of transactions only applies to the work that you do within the database itself, not any external properties. Your transaction handlers should be as fast as possible and not block on other work.

The usual practice for file uploads is to perform the file upload first, then after that succeeds, write to the database.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • So your suggestion is to handle upload first and then the call to database. How can I handle situation in which internet connection is interrupted right after the upload was done? I am new to programming so sorry if the questions are silly. – misi06 Feb 13 '18 at 18:46
  • 1
    Writes to the Realtime Database won't fail due to missing connection. They'll be retried indefinitely, as long as the app process is alive. If you have persistence enabled in the SDK, the write will also be persisted and retried if the app dies and becomes re-launched. – Doug Stevenson Feb 13 '18 at 19:08
  • I will give it a try. Thanks for tips! – misi06 Feb 13 '18 at 19:17
  • The documentation states that one line of code is enough to enable persistence. Is there any other code that has to be implemented in order to save "writes" locally and when connection is back push it to the server? It seems it doesn't work for me. – misi06 Feb 13 '18 at 21:53
  • Yes, all you have to do is write that one line of code. BTW, transactions won't retry after the app is killed - they are not persisted like normal writes (for technical reasons this is very difficult). – Doug Stevenson Feb 13 '18 at 22:04
  • Sorry for troubling you, but I have decided to test the persistence with an order of calls: exporting file to server -> if(success) then add reference to database. When I turn airplane mode on during exporting of file and turning it back, the transfer is not restored (nor database entry of course). Do you know what might be the reason? – misi06 Feb 13 '18 at 22:08
  • Please ask another question describing what you're trying to do and what's not working the way you expect. – Doug Stevenson Feb 13 '18 at 22:09