简体   繁体   中英

Firebase storage url for tableview image

I am migrating across my backend from Parse :'( to Firebase and am having some issues understand Firebase's implementation around assets and referencing them.

Essentially I need to have a JSON structure detailing some articles, each of these articles will have an image. Currently the JSON is manually added in order for the app to reference the latest articles. The images for this are manually uploaded to the storage aspect of Firebase and the file name of this is added to the JSON of the articles.

My app calls the json in order to populate a table view with a label for the heading of the article and an image in the same cell.

The problem I am having is retrieving the image URL for the storage assets in order to load the image into the tableview -

First I call the articles data from the database

  FIRDatabaseReference *ref =  [[FIRDatabase database] reference];


    [[ref child:@"articles"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {

        NSArray *articles = (NSArray *)snapshot.value;} withCancelBlock:^(NSError * _Nonnull error) {
        NSLog(@"%@", error.localizedDescription);

    }];

From the return snapshot is converted into a model object - where the article heading is set to the model object as well as the image URL generated

Article *article = [Article new];
    article.title = [articleObj valueForKey:@"title"];
    if ([articleObj objectForKey:@"image"] != [NSNull null]) {

    // Points to the root reference
    FIRStorageReference *storageRef = [[FIRStorage storage] referenceForURL:@"gs://project-3229518851181635221.appspot.com"];
    // Points to "images"
    FIRStorageReference *imagesRef = [storageRef child:@"articleImages"];

    // Note that you can use variables to create child values
    FIRStorageReference *imagePath = [imagesRef child:articleObj[@"image"]];

    if (imagePath){
        article.imageURL = [NSURL URLWithString:imagePath.fullPath];

    // Fetch the download URL
    [imagePath downloadURLWithCompletion:^(NSURL *URL, NSError *error){
        if (error != nil) {
            // Handle any errors
            NSLog(@"**ERROR %@", error.description);
            NSLog(@"**ERROR %@", URL.absoluteString);
            NSLog(@"**ERROR %@",article.title);
        } else {
            article.imageURL = URL;

        }
    }];
    }

The problem I have with this method (apart from it feeling like a lot of code for something which feels like it should be a standard property) is that the Article title is available immediately, but the 'downloadURL' block takes longer, so I either need observe when this finishes and not reload my table until each article has finished obtaining its Image URL

SO the question: Is there an alternative non blocking way to obtain the image URL Or is the URL reference I see in the storage portal for the URL reliable enough to use in my JSON instead of a reference to the image name (so store the URL in my DB rather than the image name)

Also for reference I am using SDWebimage for lazyloading images, but the URL is currently not present the first time the tablereloads due to the above mentioned delays in retrieving the URL

Thanks in advance!

You can convert your three lines of code to single line by replacing these,

// Points to the root reference
FIRStorageReference *storageRef = [[FIRStorage storage] referenceForURL:@"gs://project-3229518851181635221.appspot.com"];
// Points to "images"
FIRStorageReference *imagesRef = [storageRef child:@"articleImages"];   
// Note that you can use variables to create child values
FIRStorageReference *imagePath = [imagesRef child:articleObj[@"image"]];

to

// Points to the root reference
FIRStorageReference *storageRef = [[FIRStorage storage] referenceForURL:@"gs://project-3229518851181635221.appspot.com/articleImages/image"]];

Base on your requirement there is one extended class for SDWebImage which just take reference of FIRStorageReference and download your image.

See below code for same:

FIRStorageReference *storageRef = [[FIRStorage storage]
                                           referenceWithPath:[NSString stringWithFormat:@"/folder/images/%@",aDictCardData[@"url"]]];

        [cell.imgDetail sd_setImageWithStorageReference:storageRef
                                       placeholderImage:nil
                                             completion:^(UIImage *image,
                                                          NSError *error,
                                                          SDImageCacheType
                                                          cacheType,
                                                          FIRStorageReference *ref) {
                                                 if (error != nil) {
                                                     NSLog(@"Error loading image: %@", error.localizedDescription);
                                                 }
                                             }];

In above code you can find sd_setImageWithStorageReference method with storageRef to easily access FireBase Image .

You can find this Extended Class file from Here : https://github.com/firebase/FirebaseUI-iOS/tree/master/FirebaseStorageUI

Add This classes in your project and use this method.

Hope this will helps you to get FireBase Image without getting NSURL of that image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM