Firebase 存储 API 触发两次

Posted

技术标签:

【中文标题】Firebase 存储 API 触发两次【英文标题】:Firebase storage API triggers twice 【发布时间】:2020-04-17 08:51:40 【问题描述】:

我正在尝试使用 Google Firebase 存储 API 存储我的文件,但管道被执行了两次。有什么想法让它只触发一次吗?

// def
task: AngularFireUploadTask;
storage: AngularFireStorage;

// code
this.task = this.storage.upload(path, file,  customMetadata );
    return this.task.snapshotChanges().pipe(
        map(doc => 
            console.log('me'); // THIS IS PRINTED TWICE
            return doc;
        )
    );

【问题讨论】:

UploadTask 期间,执行上传时将有多个TaskEvent.STATE_CHANGED 事件(例如13%、42%、100%)。其中每一个都将调用使用pipe() 的链式观察者。 【参考方案1】:

根据documentation,您可以预期管道将在上传过程中收到多个快照。这些快照中的每一个都包含一些关于上传状态的信息。

如果你只是想知道什么时候上传完成,请从文档中的示例中获取代码,上传完成后获取下载 URL:

task.snapshotChanges().pipe(
    finalize(() => this.downloadURL = fileRef.getDownloadURL() )
)

【讨论】:

是的,我最终这样做了。让人们生活更轻松的疯狂 API :) 这并不疯狂 - 它提供进度更新,因此您可以执行诸如填充进度条之类的操作,这很常见。【参考方案2】:

您可以使用运算符take():

仅发出源 Observable 发出的第一个计数值。

返回 MonoTypeOperatorFunction<T>:一个 Observable,它只发出源 Observable 发出的第一个计数值,或者如果源发出的计数值少于计数值,则发出来自源的所有值。

例子:

return this.task.snapshotChanges().pipe(
  take(1),
  map(doc => 
    console.log('me');
    return doc;
  )
)

https://www.learnrxjs.io/operators/filtering/take.html

【讨论】:

不应该take 是最后一个操作员吗? last 不是更好的候选人吗?那么map只会在上传完成时被调用。 是的 last() 也可以使用 @samthecodingman 无论如何 OP 还没有回答,看看他们是否尝试过这个或没有 @all:最后或第一个 take 不起作用(没有原因)。我将代码更改为 this.task .snapshotChanges() .pipe( finalize(() => ...)) 。现在我在 finalize 中没有第二次调用。 OP 可能不想要第一个发出的快照。他们实际上可能只想要表明上传完成的那个,这将是最后一个。

以上是关于Firebase 存储 API 触发两次的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Firebase Cloud Messaging onMessage 被触发两次

Firebase Cloud 函数触发两次 onUpdate

Firebase Cloud Functions 数据库触发器“onCreate 不是函数”

如何更改firebase存储的位置?

Firebase 存储数据显示两次

Firebase:Vue.js:无法将存储与数据库连接