I'm trying to chain / pipe operations and return an Observable from a Service in angular which uses angular fire.
With promises I have this working
Service
saveDiploma(diploma: { title: any; description: any; picture: any }) {
        return new Observable(observer => {
            const id = this.db.createId();
            this.storage.ref(`diplomas/${id}/original.jpg`)
                .putString(diploma.picture, 'data_url')
                .then(task => {
                    task.ref.getDownloadURL()
                        .then(url => {
                            const saved = {
                                title: diploma.title,
                                description: diploma.description,
                                url,
                                createdAt: firebase.firestore.FieldValue.serverTimestamp(),
                                createdBy: this.auth.auth.currentUser ? this.auth.auth.currentUser.uid : 'anonymous'
                            };
                            this.db.doc(`diplomas/${id}`)
                                .set(saved)
                                .then(() => {
                                    observer.next(saved);
                                    observer.complete();
                                })
                                .catch(e => observer.error(e));
                        })
                        .catch(e => observer.error(e));
                })
                .catch(e => observer.error(e));
        });
    }
Component
save() {
        this.diplomasService.saveDiploma({
            title: this.diplomaForm.value.title,
            description: this.diplomaForm.value.description,
            picture: this.currentImage
        }).subscribe(diploma => {
            console.log('saved diploma', diploma);
        }, e => console.error('error while saving the diploma', e));
    }
I'm trying to use Observables in the service instead of Promises and pipe them in order like so
saveDiploma(diploma: { title: any; description: any; picture: any }) {
        const id = this.db.createId();
        const ref = this.storage.ref(`diplomas/${id}/original.jpg`);
        return ref.putString(diploma.picture, 'data_url').snapshotChanges().pipe(
            concatMap(task => {
                console.log('getDownloadURL');
                return from(task.ref.getDownloadURL());
            }),
            concatMap(url => {
                console.log('url', url);
                const saved = {
                    title: diploma.title,
                    description: diploma.description,
                    url,
                    createdAt: firebase.firestore.FieldValue.serverTimestamp(),
                    createdBy: this.auth.auth.currentUser ? this.auth.auth.currentUser.uid : 'anonymous'
                };
                return from(this.db.doc(`diplomas/${id}`).set(saved));
            })
        );
    }
but the getDownloadURL method is getting fired before the upload is complete and hence returning an error storage/object-not-found. I've tried adding a finalize or filter (on task.state == 'success') before the concatMap(getDownloadURL) but I have failed getting it to work.
Does anyone know how to pipe this operations and return an Observable from them?
I'm using Angular 8.1.2, Angular Fire 5.2.1 and rxjs 6.5.1