从Firebase云存储中检索图像

时间:2017-07-12 15:44:22

标签: angular firebase google-cloud-storage observable firebase-storage

我在 Angular 4 中创建了一个聊天应用,用户可以在其中发送聊天消息(文本)和媒体。我使用 Firebase 来存储所有对话,消息和成员。而云端存储用于存储文件。

我已经存储了一些附有媒体(图片)的消息,但我无法在对话视图中加载这些图片。

根据https://firebase.google.com/docs/storage/web/download-files,我可以通过以下方式下载这些文件:

const storageRef = this.firebaseApp.storage().ref().child(message.media.path + message.media.filename);
storageRef.getDownloadURL().then(url => console.log(url));

哪个确实有效,因为我可以在控制台输出中看到网址,点击它会显示我上传的图片。

示例输出网址:

https://firebasestorage.googleapis.com/v0/b/<databasename>.appspot.com/o/messages%2Fconversation1%2Fmessage1%2Fmedia%2F91615172-find-a-lump-on-cats-skin-632x475.jpg?alt=media&token=<sometoken>

我的问题是如何在我的message.component.html模板中显示这个。 我尝试过以下方法:

  

尝试1:

message.component.html:

<img src="{{message.media?.url}}">

chat.service.ts:

public retrieveMessages(conversationId) {
    this.messages = this.db.list('messages/' + conversationId, {query: {limitToLast: 10}});
    this.messages.subscribe(messages => {
        this.appendMessagesWithMediaURL(messages);
    });
}

public appendMessagesWithMediaURL(messages) {
    for (const message of messages) {
        if (message.media) { // message has media
            this.firebaseApp.storage().ref().child(message.media.path + message.media.filename).getDownloadURL().then(url => message.media.url = url);
        }
    }
}

这将设置所有&#39; src&#39;属于&#39; unknown&#39;。我认为这是因为视图加载时不存在.url属性(首先检索消息,然后我们声明并初始化.url属性)。

  

尝试2:

message.component.html:

<img src="{{(chatService.getMediaURL(message) | async)}}">

chat.service.ts:

public getMediaURL(message) {
    return new Observable(observer => {
        if (message.media) {
            const storageRef = this.firebaseApp.storage().ref().child(message.media.path + message.media.filename);
            storageRef.getDownloadURL().then(url => observer.next(url));
        }
    });
}

当我加载message.component时,这会使我的Angular应用程序挂起。 (几秒钟内RAM使用率> 1GB,标签不再响应。)请注意,我只加载了10封邮件,其中只有2封确实有1张单张图像的媒体属性(200KB)每个)。

  

其他信息

Firebase布局:

"messages": {
    "conversation1": {
        "message1": {
            "content": "Hello World",
            "media": {
                "path": "/messages/conversation1/message1/",
                "filename": "picture.png",
                "type": "image/jpeg"
            }
        }
    }
}

我用作&#39;如何检索图片的参考示例&#39;:Accessing firebase.storage() with AngularFire2 (Angular2 rc.5)

conversation.component.html

的片段
<!-- BEGIN Conversation  !-->
<div class="chat-inner" id="my-conversation">
    <!-- BEGIN Message  !-->
        <chassis-message *ngFor="let message of chatService.messages | async" [message]="message"></chassis-message>
    <!-- END Message  !-->
</div>
<!-- BEGIN Conversation  !-->

message.component.ts的片段

import { Component, Input } from '@angular/core';
import { ChatService } from '../chat.service';

@Component({
    selector: 'chassis-message',
    templateUrl: './message.component.html',
    styleUrls: ['./message.component.css'],
})
export class MessageComponent {
    @Input() message: any;

    constructor(private chatService: ChatService) {
    }
}
  

问题

检索这些图像的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

试试这些:

在message.component.ts中,创建一个简单的方法(getMediaURL),它将调用chatservice并保存url,如下所示:

private url;

constructor(private chatService: ChatService) {
    this.getMediaURL('/messages/awesome.jpg');
}

private getMediaURL(imageRef) {
    const that = this;
    this.chatService.getMediaURL(imageRef).then(url => that.url = url);
}

更新您的html以反映更改:

<img [src]="url">

然后将所需方法添加到chat.service.ts:

public getMediaURL(image): firebase.Promise<any> {
    const storageRef = this.firebaseApp.storage().ref().child(image);
    return storageRef.getDownloadURL().then(url => {
        console.log('firebase response: ' + url);
        return url;
    });
}

答案 1 :(得分:-1)

我希望您这样做可能会解决问题。

就像访问firebase存储的示例一样。在组件中存储图像URL。他们在构造函数中这样做。

 url:yourobject;
 constructor(@Inject(FirebaseApp) firebaseApp: any) {
    const storageRef = firebaseApp.storage().ref().child('images/image.png');
    storageRef.getDownloadURL().then(url => this.image = url);
  }

现在,您可以在模板中访问网址或图片

{{url?.image}}

或者如果它是你直接使用ngIf的网址

<div *ngIf = "url">
   {{url}}
</div>