我在 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) {
}
}
问题
检索这些图像的正确方法是什么?
答案 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>