Skip to content

App crashes when using Storage from a Firestore completion handler #356

Open
@mark-grimes

Description

@mark-grimes

[REQUIRED] Please fill in the following fields:

  • Pre-built SDK from the website or open-source from this repo: website
  • Firebase C++ SDK version: 7.1.1
  • Main Firebase Components in concern: Firestore, Storage
  • Other Firebase Components in use: Auth
  • Platform you are using the C++ SDK on: Mac
  • Platform you are targeting: iOS

[REQUIRED] Please describe the question here:

Briefly

Is it safe to call other firebase methods from a future OnCompletion handler? That is, start a second (or more) asynchronous task when the first completes?

In detail

This is potentially a regression, but could be a misuse of the API on our part. We've been using Firebase 6.15.1 successfully for a while and decided it was past time to upgrade to 7.1.1. We have a design where configuration is stored in Firestore, which tells the app which files are required from Cloud Storage. So for one call to our internal function we need a call to Firestore followed by a call to Storage. Simplified code would be something like:

void getCorrectFile( const char* localPath, std::function<void(const std::string& errorMessage)> callback )
{
    pFirestore->Collection("configStuff").Get().OnCompletion(
        [callback=std::move(callback)]( const ::firebase::Future<firebase::firestore::QuerySnapshot>& collectionFuture )
        {
            if( collectionFuture.error() != firebase::firestore::Error::kErrorOk )
            {
                callback( "An error occurred (real code maps errors to error_codes)" );
            }
            else
            {
                // ...code to work out correct file from the QuerySnapshot...
                firebase::storage::StorageReference fileRef = pStorage->GetReference(firebasePath);

                fileRef.GetFile(localPath).OnCompletion( [callback=std::move(callback),fileRef](const firebase::Future<size_t>& getFileFuture)
                {
                    if( getFileFuture.error() != 0 ) callback( getFileFuture.error_message() );
                    else callback( "No error (real code would create default constructed error_code)" );
                } );
            }
        } );
}

As I say, this all worked fine in Firebase 6.15.1. After upgrading to 7.1.1 we now get various crashes[*]. Before investigating I thought it was worth checking we're not fundamentally abusing the thread model in the API, and it just happened to work previously.

[*] How it crashes is fairly inconsistent. It can be an assert from some mutex.h file, or an unhandled *** -[NSFileManager createDirectoryAtURL:withIntermediateDirectories:attributes:error:]: URL is nil exception. I've even seen it work once.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions