【问题标题】:Firebase 'bytesTransferred': Property 'bytesTransferred' does not exist on type 'Object'Firebase“bytesTransferred”:“对象”类型上不存在属性“bytesTransferred”
【发布时间】:2018-01-12 00:59:23
【问题描述】:

我正在使用什么

  • 角度
  • Firebase

我有什么

  • 允许我上传到 Firebase 存储和实时数据库的上传服务
  • 这已经好几个星期了

问题

  • 今天早上不行。

  • 我没有更改与此文件或其组件有关的任何内容

  • 我唯一改变的是一个 firebase npm install 来尝试让其他一些废话工作

  • 这实际上完全停止了我的项目

  • 我的服务现在在构建时显示错误:

[ts]“对象”类型上不存在属性“bytesTransferred”

[ts]“对象”类型上不存在属性“totalBytes”。

'() => void' 类型的参数不能分配给'Unsubscribe' 类型的参数。 类型 'void' 不能分配给类型 'undefined'。

问题

  • 有谁知道为什么会突然出现这个错误信息?

我的上传服务

import { Injectable, OnDestroy } from '@angular/core';
import { Upload } from './upload';
import { AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2/database';
import * as firebase from 'firebase';
import { AuthService } from '../../user/auth.service';
import { Subscription } from 'rxjs/Subscription';

// Routes
import { Router, ActivatedRoute } from '@angular/router';

@Injectable()
export class ProjectsAddService implements OnDestroy {
  private _subscription: Subscription;
  private basePath: string = '/site_photo';
  uploads: FirebaseListObservable<Upload[]>;

  constructor(
    private db: AngularFireDatabase, 
    private authService: AuthService, 
     private router: Router
  ) { }






  getUploads(query = {}) {
    this.uploads = this.db.list(this.basePath, {
      query: query
    });
    return this.uploads
  }


  deleteUpload(upload: Upload) {
    this.deleteFileData(upload.$key)
      .then(() => {
        this.deleteFileStorage(upload.name)
      })
      .catch(error => console.log(error))
  }

  // Writes the file details to the realtime db
  private deleteFileData(key: string) {
    return this.db.list(`${this.basePath}/`).remove(key);
  }

  // Firebase files must have unique names in their respective storage dir
  // So the name serves as a unique key
  private deleteFileStorage(name: string) {
    const storageRef = firebase.storage().ref();
    storageRef.child(`${this.basePath}/${name}`).delete()
  }

  ngOnDestroy() {
    if (this._subscription) {
      this._subscription.unsubscribe();
    }
  }

  submitForm(title: string, reference: string, date: string, auditorName: string, newCompanyName: string, upload: Upload) {
    this._subscription = this.authService.user.subscribe(user => {
      if (user) {

        // The User ID of the current user
        var userId = user.uid;

        // Generate a new firebase key to be used for the Project, Project List, Project Members and Storage References
        var newPostKey = firebase.database().ref().child('project_list').push().key;

        // Create a reference to the firebase storage
        const storageRef = firebase.storage().ref();
        const uploadTask = storageRef.child('site_photo/' + user.uid + '/' + newPostKey + '/site_photo').put(upload.file);

        uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
          (snapshot) => {
            // upload in progress
            upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          },
          (error) => {
            // upload failed
            console.log(error)
          },
          () => {
            // upload success
            upload.url = uploadTask.snapshot.downloadURL
            upload.name = upload.file.name

            // Data to be added to the 'Project' node
            var albumDetails = {
              album_title: title,
              label_name: newCompanyName,
              album_photo: upload.url
            }

            // Data to be added to the 'Project_list' node
            var albumList = {
              label_name: newCompanyName,
              album_photo: upload.url
            }

            // Data to be added to the 'Project_members' node
            var userList = {
              [userId]: true
            }

            // Group the updates to the associated firebase nodes
            var updates = {};
            updates['/album/' + user.uid + '/' + newPostKey] = projectsDetails;
            updates['/album_list/' + user.uid + '/' + newPostKey] = projectsList;
            updates['/project_members/' + newPostKey] = userList;


            // Once the image has been successfully uploaded, make an update to the realtime database
            this.saveToRealtimeDatabase(updates);

            this.router.navigate(['projects']);
          }
        );

      }

    });


  }

  // Perform an atomic Multi-Path update
  private saveToRealtimeDatabase(updates) {
    return firebase.database().ref().update(updates);
  }


}

这里的任何帮助将不胜感激。完全被这个弄糊涂了。




更新

我注意到,如果我注释掉以下代码,它会正确编译。我只是读错了上传进度。

          (snapshot) => {
            // upload in progress
            upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          },
          (error) => {
            // upload failed
            console.log(error)
          },

第二次更新 以下工作,但感觉有点奇怪。任何帮助将不胜感激。

        var snapshotRef = snapshot as firebase.storage.UploadTaskSnapshot;
        var bytesTransferred = (snapshotRef).bytesTransferred;
        var totalBytes = (snapshotRef).totalBytes;
        upload.progress = (bytesTransferred / totalBytes) * 100;

【问题讨论】:

  • 我也有同样的问题,还没找到解决办法

标签: angular firebase angularfire firebase-storage


【解决方案1】:

有同样的问题。通过设置快照的类型来修复。这是打字稿。

uploadTask.on('state_changed', (snapshot: firebase.storage.UploadTaskSnapshot) => {
    upload.progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
}

【讨论】:

    【解决方案2】:

    我也有同样的问题 我通过在构造函数之前声明 uploadtask 和所有其他变量来解决它,然后简单地使用 this.uploadTask 来使用它

    storageRef = firebase.storage().ref();
        file : any;
       uploadTask: any;
    
    
    
    this.uploadTask = this.storageRef.child('images/${this.file.name}').put(this.file,metadata);
    
            this.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, function(snapshot){...}
    

    【讨论】:

    • 但我的上传卡在“上传正在运行”中,即使在上传图片后也是如此
    • 我建议 Alfred_P 的答案是 100% 正确的,它应该被标记为正确,因为它是唯一的出路!
    【解决方案3】:

    将您的代码 sn-p 替换为以下代码。

    uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
      (snapshot) =>  {
        upload.progress = (uploadTask.snapshot.bytesTransferred / uploadTask.snapshot.totalBytes) * 100;
        console.log(upload.progress);
      },
    

    【讨论】:

    • 退订部分出错。我收到此错误:` type '() => void ' 的参数不可分配给'Unsubscribe' 类型的参数。类型 'void' 不能分配给类型 'undefined'。 `
    • 你能不能也回答我的问题。我使用您的解决方案修复了第一部分。 @Hasi
    【解决方案4】:

    我对 typescript 或这个包的了解不够,无法准确解释发生了什么,但至少我可以修复它。

    显然新版本中的完整回调不再接受任何作为返回类型,而只是未定义。我认为这与返回未定义的默认取消订阅有关。在您的代码中,您可以通过在回调中手动返回 undefined 来修复错误。

    () => {
        console.log('upload complete');
        return undefined;
    }
    

    Typescript 显然无法在第一个回调中推断出快照的类型,您还需要手动指定它,您可以使用类型转换,也可以从回调中调用单独的函数。

     console.log((snapshot as firebase.storage.UploadTaskSnapshot).bytesTransferred);
    

    如果有人有更深入的解释,我将不胜感激。

    【讨论】:

    • 嘿 Alfred,我很高兴其他人遇到了这个问题。我快疯了!在我上面的代码中,'return undefined' 会放在'this.router.navigate(['projects']);'下吗?在我上面的示例中,您的第二行代码会放在哪里?
    • 我也很困惑,为什么在它工作了这么久的情况下今天早上决定中断。
    • 是的,返回 undefined 应该在该行下方。您需要将 snapshot.bytesTransferred 更改为 (snapshot as firebase.storage.UploadTaskSnapshot).bytesTransferred 并且对 totalBytes 执行相同操作
    • “console.log”部分呢?我想知道这个错误是否与 angular cli 版本或 firebase 安装有关。
    • 控制台日志只是在我自己的代码中,用于测试转换是否有效,您不需要它,并且可能不希望在生产代码中使用它
    猜你喜欢
    • 1970-01-01
    • 2019-10-11
    • 2018-02-10
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-23
    • 2020-05-01
    相关资源
    最近更新 更多