-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(storage): snapshotChanges should return a success snapshot (#2704)
* Works on tasks that are already running * Now appropriately emits a final success snapshot before completion * In theory should emit a canceled or error snapshot before throwing (once the JS SDK is patched) * Added tests for canceling, pausing, and resuming
- Loading branch information
1 parent
984006d
commit 972aa85
Showing
2 changed files
with
92 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,40 @@ | ||
import { Observable } from 'rxjs'; | ||
import { shareReplay } from 'rxjs/operators'; | ||
import { debounceTime } from 'rxjs/operators'; | ||
import { UploadTask, UploadTaskSnapshot } from '../interfaces'; | ||
|
||
// need to import, else the types become import('firebase/app').default.storage.UploadTask | ||
// and it no longer works w/Firebase v7 | ||
import firebase from 'firebase/app'; | ||
|
||
// Things aren't working great, I'm having to put in a lot of work-arounds for what | ||
// appear to be Firebase JS SDK bugs https://github.com/firebase/firebase-js-sdk/issues/4158 | ||
export function fromTask(task: UploadTask) { | ||
return new Observable<UploadTaskSnapshot>(subscriber => { | ||
const progress = (snap: UploadTaskSnapshot) => subscriber.next(snap); | ||
const error = e => subscriber.error(e); | ||
const complete = () => subscriber.complete(); | ||
task.on('state_changed', progress, (e) => { | ||
// emit the current snapshot, so they don't have to wait for state_changes | ||
// to fire next... this is stale if the task is no longer running :( | ||
progress(task.snapshot); | ||
const unsub = task.on('state_changed', progress); | ||
// it turns out that neither task snapshot nor 'state_changed' fire the last | ||
// snapshot before completion, the one with status 'success" and 100% progress | ||
// so let's use the promise form of the task for that | ||
task.then(snapshot => { | ||
progress(snapshot); | ||
complete(); | ||
}, e => { | ||
// TODO investigate, again this is stale, we never fire a canceled or error it seems | ||
progress(task.snapshot); | ||
error(e); | ||
}, () => { | ||
progress(task.snapshot); | ||
complete(); | ||
}); | ||
// on's type if Function, rather than () => void, need to wrap | ||
return function unsubscribe() { | ||
unsub(); | ||
}; | ||
}).pipe( | ||
shareReplay({ bufferSize: 1, refCount: false }) | ||
// deal with sync emissions from first emitting `task.snapshot`, this makes sure | ||
// that if the task is already finished we don't emit the old running state | ||
debounceTime(0) | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters