未捕获的类型错误:无法读取未定义的属性“存储”[重复]

Posted

技术标签:

【中文标题】未捕获的类型错误:无法读取未定义的属性“存储”[重复]【英文标题】:Uncaught TypeError: Cannot read property 'storage' of undefined [duplicate] 【发布时间】:2019-09-15 07:16:48 【问题描述】:

我正在将图像上传到 firebase,然后尝试将其下载 URL 保存到 ionic storage,但它给了我这个错误

Uncaught TypeError: Cannot read property 'storage' of undefined

这是我的代码:

import  Injectable  from '@angular/core';
import  AngularFirestore, AngularFirestoreCollection  from '@angular/fire/firestore';
import  Observable  from 'rxjs';
import  map  from 'rxjs/operators';
import * as firebase from 'firebase';
import  Storage  from '@ionic/storage';
import uuid from 'uuid/v1'; //here change 'v1' with the version you desire to use

export interface Dress 
  id?: string;
  title: string;
  description: string;
  createdAt: number;
  category: string;
  price: number;
  city: string;
  type: string;
  size: string;
  action: string;
  image_1: string;
  image_2: string;
  image_3: string;

export interface Category 
  name: string;

export interface City 
  name: string;

export interface Type 
  name: string;

export interface Size 
  name: string;

export interface Action 
  name: string;


@Injectable(
  providedIn: 'root'
)
export class DressService 
  private dressCollection: AngularFirestoreCollection<Dress>;
  private dress: Observable<Dress[]>;
  private categoryCollection: AngularFirestoreCollection<Category>;
  private category: Observable<Category[]>;
  private cityCollection: AngularFirestoreCollection<City>;
  private city: Observable<City[]>;
  private typeCollection: AngularFirestoreCollection<Type>;
  private type: Observable<Type[]>;
  private sizeCollection: AngularFirestoreCollection<Size>;
  private size: Observable<Size[]>;
  private actionCollection: AngularFirestoreCollection<Action>;
  private action: Observable<Action[]>;
  id = uuid();

  constructor(db: AngularFirestore,
              public storage: Storage,
  ) 
    this.dressCollection = db.collection<Dress>('dress');
    this.dress = this.dressCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
    this.categoryCollection = db.collection<Category>('categories');
    this.category = this.categoryCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
    this.cityCollection = db.collection<City>('cities');
    this.city = this.cityCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
    this.typeCollection = db.collection<Type>('types');
    this.type = this.typeCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
    this.sizeCollection = db.collection<Size>('sizes');
    this.size = this.sizeCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
    this.actionCollection = db.collection<Action>('actions');
    this.action = this.actionCollection.snapshotChanges().pipe(
      map(actions => 
        return actions.map(a => 
          const data = a.payload.doc.data();
          const id = a.payload.doc.id;
          return  id, ...data ;
        );
      )
    );
  
  getDresses() 
    return this.dress;
  
  getCategories() 
    return this.category;
  
  getTypes() 
    return this.type;
  
  getCities() 
    return this.city;
  
  getSizes() 
    return this.size;
  
  getActions() 
    return this.action;
  
  getDress(id) 
    return this.dressCollection.doc<Dress>(id).valueChanges();
  
  updateDress(dress: Dress, id: string) 
    return this.dressCollection.doc(id).update(dress);
  
  addDress(dress: Dress) 
    return this.dressCollection.add(dress);
  
  removeDress(id) 
    return this.dressCollection.doc(id).delete();
  
  uploadImage(img, numb) 
    const ref = firebase.database().ref('Uploads');
    const storage = firebase.storage();
    const pathReference = storage.ref('images/' + this.id + numb + '.jpg');
    const message = img;
    pathReference.putString(message, 'base64',  contentType: 'image/jpg' ).then(function (snapshot) 
      console.log('Uploaded a base64url string!');
      pathReference.getDownloadURL().then(function (url) 
        console.log(url);
        console.log(typeof(url));
        if (numb === 1) 
          this.storage.set('image_1_url', url);
        
        if (numb === 2) 
          this.storage.set('image_2_url', url);
        
        if (numb === 3) 
          this.storage.set('image_3_url', url);
        
      );
    );


  

当我在选择图像后调用uploadImage()函数时,它已经上传并生成了URL但它无法保存它,错误来自这一行

        if (numb === 1) 
          this.storage.set('image_1_url', url);
        

我的 firebase 配置正确,一切正常,只有在 ionic storage 部分失败

【问题讨论】:

你应该在uploadImage()函数中使用箭头函数 你看过https://***.com/a/41352560/9901630 firebase.storage 已弃用,请改用 gcloud.storage :***.com/a/39848966/9941039 @nullptr.t 上传和存储在线文件的过程运行良好。当我尝试在本地保存 URL 以供以后重用时出现问题 我现在明白了 - 问题是您正在尝试使用 storage.set('name', 'Max'); 这是离子存储对象的一种方法,但您也将 firebase.storage 设置为存储对象,尝试重新命名 firebase 存储对象以区分它与离子存储。 【参考方案1】:

请在匿名函数上使用胖箭头函数,因为前者不会创建自己的执行范围,而后者会这样做,因此您的“this”开始指向它:

uploadImage(img, numb) 
    const ref = firebase.database().ref('Uploads');
    const storage = firebase.storage();
    const pathReference = storage.ref('images/' + this.id + numb + '.jpg');
    const message = img;
    pathReference.putString(message, 'base64',  contentType: 'image/jpg' ).then(function (snapshot) 
      console.log('Uploaded a base64url string!');
      // see here replaced 'function()' with =>:
      pathReference.getDownloadURL().then((url)=>
        console.log(url);
        console.log(typeof(url));
        if (numb === 1) 
          this.storage.set('image_1_url', url);
        
        if (numb === 2) 
          this.storage.set('image_2_url', url);
        
        if (numb === 3) 
          this.storage.set('image_3_url', url);
        
      );
    );


  

【讨论】:

以上是关于未捕获的类型错误:无法读取未定义的属性“存储”[重复]的主要内容,如果未能解决你的问题,请参考以下文章

网格存储配置抛出“未捕获的类型错误:无法读取未定义的属性‘缓冲’”

如何在应用程序加载期间捕获“未捕获的类型错误:无法读取未定义的属性‘isModel’?

未捕获的类型错误:无法读取切换功能中未定义的属性“prop”

错误::未捕获(承诺中)类型错误:无法读取未定义的属性“内容”

未捕获的类型错误:无法读取未定义的属性“长度”

未捕获的类型错误:无法读取 chrome 扩展中未定义的属性“本地”