【问题标题】:Uploading images to Firebase将图片上传到 Firebase
【发布时间】:2016-01-29 17:57:30
【问题描述】:

我正在尝试像这样将图像上传到 Firebase:

Firebase *ref = [[Firebase alloc] initWithUrl:@"https://<app-name>.firebaseio.com/posts"];
Firebase *newPost = [ref childByAutoId];

NSDictionary *newPostData = @{
                              @"image" : [self encodeToBase64String:image]
                              };
[newPost updateChildValues:newPostData];

我正在使用此代码对图像进行编码:

- (NSString *)encodeToBase64String:(UIImage *)image {
return [UIImagePNGRepresentation(image) base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
}

但这不起作用,因为字符串超过了最大大小:

Terminating app due to uncaught exception 'InvalidFirebaseData', reason: '(updateChildValues:) String exceeds max size of 10485760 utf8 bytes:

我可以做些什么来解决这个问题?使用 Firebase 时,我没有在网上找到任何关于 iOS 开发和图像的信息。

【问题讨论】:

标签: ios objective-c uiimage firebase compression


【解决方案1】:

如果图像太大,您应该存储一个较小的图像。让我引用自己的话:How do you save a file to a Firebase Hosting folder location for images through android?

Firebase 数据库允许您存储 JSON 数据。虽然二进制数据不是 JSON 支持的类型,但可以使用 base64 对二进制数据进行编码,从而将图像存储在(大)字符串中。 [但是] 虽然这是可能的,但不建议将其用于小图像或好奇是否可以这样做。

您的最佳选择通常是将图像存储在第 3 方图像存储服务上。

【讨论】:

  • 我使用了这种方法。将图像本身存储在 Amazon S3 中,并在 Firebase 中对其进行引用
  • 酷。您可以分享一些关键代码作为答案吗?这对其他人非常有用。
  • 我可以在这里问你一个简单的问题而不打开一个新的 SO 问题吗?我正在删除值,但是因为我需要删除多个路径上的值 - 例如,我是否必须执行一个 for 循环并多次运行 .remove() ,或者在添加时是否有像 updateChildValues 这样更有效的方法价值观?
  • 如果您使用 null 值更新路径,则该路径中的任何现有值都将被删除。所以update({ "path/to/first": null, "another/path": null }) 会删除两个值。
  • NSNull想出来
【解决方案2】:

正如 Frank van Puffelen 建议的那样,我的解决方案是使用 Amazon S3 进行想象存储,并使用 Firebase 存储对图像位置的引用。

我创建了一个名为uploadImage: 的方法,它看起来像这样:

-(void)uploadImage:(UIImage *)image
{
// Create reference to Firebase
Firebase *ref = [[Firebase alloc] initWithUrl:@"https://<MY-APP>.firebaseio.com"];
Firebase *photosRef = [ref childByAppendingPath:@“photos];
Firebase *newPhotoRef = [photosRef childByAutoId];

// Image information
NSString imageId = [[NSUUID UUID] UUIDString];

// Create dictionary containing information
NSDictionary photoInformation = @{
                                @“photo_id” : imageId
                                // Here you can add more information about the photo
                                };

NSString *imagePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageId]];
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:imagePath atomically:YES];

NSURL *imageUrl = [[NSURL alloc] initFileURLWithPath:imagePath];
AWSS3TransferManagerUploadRequest *uploadRequest = [AWSS3TransferManagerUploadRequest new];
uploadRequest.bucket = @“<AMAZON S3 STORAGE NAME>“; // create your own by setting up an account on Amazon aws.
uploadRequest.key = imageId;
uploadRequest.contentType = @"image/png";
uploadRequest.body = imageUrl;

AWSS3TransferManager *transferManager = [AWSS3TransferManager defaultS3TransferManager];
[[transferManager upload:uploadRequest] continueWithExecutor:[AWSExecutor mainThreadExecutor] withBlock:^id(AWSTask *task) {
    if (!task.error) {
        // Update Firebase with reference
        [newPhotoRef updateChildValues:currentPHD withCompletionBlock:^(NSError *error, Firebase *ref) {
            if (!error) {
                [newPhotoRef updateChildValues:photoInformation withCompletionBlock:^(NSError *error, Firebase *ref) {
                    if (!error) {
                        // Uploaded image to Amazon S3 and reference to Firebase
                    }
                }];
            }
        }];
    } else {
        // Error uploading
}
return nil;
}];
}

编辑 该方法应该是一个块方法,如下所示:

-(void)uploadImage:(UIImage *)image withBlock:(void (^)(Firebase *ref, NSError *error, AWSTask *task))handler
{
    // upload
}

【讨论】:

  • 这是我制作的第一种上传图片的方法,后来我将其更改为块方法,并在一次更新中执行 Firebase 更新,而不是两次不同。这可以通过多位置更新来实现,例如创建这样的字典:NSDictionary *firebaseUpdate = @{first_path : first_update, second_path : second update}
猜你喜欢
  • 2018-06-14
  • 2020-12-05
  • 1970-01-01
  • 2016-12-24
  • 2020-04-01
  • 2020-06-24
  • 2020-09-07
  • 2018-02-26
相关资源
最近更新 更多