0

I am using and Angular and Firebase, to upload images to Firebase storage and display them. I am trying to display only the images uploaded by the specific user. But when i do that, all the images uploaded(by all users) in the Firebase are displayed.

what changes i should make? Below is my code

Gallerycomponent.ts

import { Component, OnInit, OnChanges } from '@angular/core';
import { ImageService } from '../services/image.service';
import { GalleryImage } from '../models/galleryImage.model';
import { Observable } from 'rxjs/Observable';

@Component({
selector: 'app-gallery',
templateUrl: './gallery.component.html',
styleUrls: ['./gallery.component.css']
})
export class GalleryComponent implements OnInit, OnChanges {
  images: Observable<GalleryImage[]>;

constructor(private imageService: ImageService) { }

 ngOnInit() {
  this.images = this.imageService.getImages();
 }

ngOnChanges() {
  this.images = this.imageService.getImages();
 }
}

gallerycomponent.html

<div class="row">
    <h2>Latest Photos</h2>
    <ul id="thumbnailsList">
        <li *ngFor="let image of images | async" class="img">
            <a [routerLink]="['/image', image.$key]">
            <img src="{{image.url}}" class="tn">
            </a>
        </li>
    </ul>
</div>

image.service.ts (*have removed the import from this )

@Injectable()
export class ImageService {
  private uid: string;

  constructor(private afAuth: AngularFireAuth, private db: AngularFireDatabase) { 
    this.afAuth.authState.subscribe(auth => {
      if (auth !== undefined && auth !== null) {
        this.uid = auth.uid;
      }
    });
  }

  getImages(): Observable<GalleryImage[]> {
    return this.db.list('uploads');
  }

  getImage(key: string) {
    return firebase.database().ref('uploads/' + key).once('value')
    .then((snap) => snap.val());
  }
}

upload service.ts

@Injectable()
export class UploadService {

  private basePath = '/uploads';
  private uploads: FirebaseListObservable<GalleryImage[]>;

  constructor(private ngFire: AngularFireModule, private db: AngularFireDatabase) { }

  uploadFile(upload: Upload) {
    const storageRef = firebase.storage().ref();
    const uploadTask = storageRef.child(`${this.basePath}/${upload.file.name}`)
      .put(upload.file);

    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
      // three observers
      // 1.) state_changed observer
      (snapshot) => {
        // upload in progress
        upload.progress = (uploadTask.snapshot.bytesTransferred / uploadTask.snapshot.totalBytes) * 100;
        console.log(upload.progress);
      },
      // 2.) error observer
      (error) => {
        // upload failed
        console.log(error);
      },
      // 3.) success observer
      (): any => {
        upload.url = uploadTask.snapshot.downloadURL;
        upload.name = upload.file.name;
        this.saveFileData(upload);
      }
    );
  }
  private saveFileData(upload: Upload) {
    this.db.list(`${this.basePath}/`).push(upload);
    console.log('File saved!: ' + upload.url);
  }
}

any help would be appreciated. Thank you.

lokanath
  • 237
  • 6
  • 16
  • Have you looked at [queries for AngularFire](https://github.com/angular/angularfire2/blob/master/docs/rtdb/querying-lists.md)? You just need something along the lines of `db.list('/images', ref => ref.orderByChild('user').equalTo('kato'))` – Kato Apr 23 '18 at 23:12

1 Answers1

0

So there are a couple ways to go about handling this issue, but for starters, you're going to need to store the user in the database in some facet so that you can recall all instances of images that were uploaded by that user. I'm not sure what you're using to get the user's profile (i.e. firebase side of things or input field in your app), but again you will need to store that in the database.

For implementing this in your code, I would suggest something like this:

// 3.) success observer
  (): any => {
    upload.url = uploadTask.snapshot.downloadURL;
    upload.name = upload.file.name;
    upload.user = upload.[WHATEVER SERVICE YOU'RE STORING THE USER IN].username;
    this.saveFileData(upload);
  }

Once you have this, when you're recalling the images, you could still grab images the same way you're handling it but also add an ngIf condition to your loop so it would look something like:

gallerycomponent.html

<div class="row">
<h2>Latest Photos</h2>
<ul id="thumbnailsList">
    <li *ngFor="let image of images | async" class="img">
      <div *ngIf="image.user == 'username'">
        <a [routerLink]="['/image', image.$key]">
        <img src="{{image.url}}" class="tn">
        </a>
      </div>
    </li>
</ul>

One thing to note is that you can't have more than one structural directive on the same element, so that's why the extra div is added.

mclem
  • 128
  • 7