【问题标题】:Function DocumentReference.set() called with invalid data使用无效数据调用的函数 DocumentReference.set()
【发布时间】:2020-04-18 15:54:27
【问题描述】:

我正在尝试将图片和标题从 Angular 网站上传到 Firestore。

这是我的模板。

<form #form="ngForm" autocomplete="off" (submit)="onSubmit(form)">
    <div class="form-group">
        <input type="text" name="title" id="title" #title="ngModel" [(ngModel)]="service.timetable.title">
    </div>
    <div class="form-group">
        <input hidden type="text" name="id" id="id" #id="ngModel" [(ngModel)]="service.timetable.id">
    </div>
    <div class="form-group">
        <input hidden type="text" name="imgurl" id="imgurl" #imgurl="ngModel" [(ngModel)]="service.timetable.imgurl">
    </div>
    <div class="form-group">
        <input type="file" name="timetable" id="timetable" (change)="uploadImage($event)">
    </div>
    <div>

    </div>
    <button type="submit">Submit</button>
</form>

这是我的打字稿文件

import { TimetableService } from './../../shared/timetable.service';
import { AngularFirestore } from '@angular/fire/firestore';
import { NgForm } from '@angular/forms';
import { AngularFireStorage } from '@angular/fire/storage';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-timetable',
  templateUrl: './timetable.component.html',
  styleUrls: ['./timetable.component.css']
})
export class TimetableComponent implements OnInit {

  selectedFile =null;

  constructor(private storage: AngularFireStorage, private firebase: AngularFirestore, private service: TimetableService) { }

  ngOnInit() {
    this.resetForm();

  }

  resetForm(form?: NgForm){
    if(form!=null)
    form.resetForm();
    this.service.timetable ={
      id: null,
      title:"",
      imgurl:""
    };
  }

  async onSubmit(form: NgForm){

    let dataa = Object.assign({},form.value);// id, imgurl, title
    delete dataa.id;
    let filepath = 'timetable'+ dataa.title;
    const task =this.storage.upload(filepath, this.selectedFile );
    await task;
    const imageurl =(await task).downloadURL;

    dataa.imgurl = imageurl;

    this.firebase.collection('timetabledata').add(dataa);

  }

  uploadImage(event){
    this.selectedFile = event.target.files[0];
  }

}

当我点击提交按钮时出现此错误

ERROR Error: Uncaught (in promise): FirebaseError: [code=invalid-argument]: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field imgurl)
FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field imgurl)
    at new FirestoreError (index.cjs.js:350)
    at ParseContext.push../node_modules/@firebase/firestore/dist/index.cjs.js.ParseContext.createError (index.cjs.js:20355)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseScalarValue (index.cjs.js:20702)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (index.cjs.js:20568)
    at index.cjs.js:20584
    at forEach (index.cjs.js:454)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseObject (index.cjs.js:20583)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (index.cjs.js:20542)
    at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseSetData (index.cjs.js:20407)
    at DocumentReference.push../node_modules/@firebase/firestore/dist/index.cjs.js.DocumentReference.set (index.cjs.js:21384)
    at resolvePromise (zone-evergreen.js:797)
    at zone-evergreen.js:707
    at fulfilled (tslib.es6.js:70)
    at ZoneDelegate.invoke (zone-evergreen.js:359)
    at Object.onInvoke (core.js:39698)
    at ZoneDelegate.invoke (zone-evergreen.js:358)
    at Zone.run (zone-evergreen.js:124)
    at zone-evergreen.js:855
    at ZoneDelegate.invokeTask (zone-evergreen.js:391)
    at Object.onInvokeTask (core.js:39679)

我想将图像上传到 Firestore 存储,获取 downloadUrl,然后将 title 和 downloadUrl 保存在 firestore 中。当我需要编辑记录时,我需要将这些数据放入表单中。 我应该怎么做才能解决这个问题?

我对问题进行了编辑。以前错误发生在“id”字段中,我已经修复了它。这是一个愚蠢的错误。但现在它发生在“imgurl”字段中。

【问题讨论】:

  • Firestore 文档中不允许有未定义的值。这就是错误消息试图告诉您的内容,它还为您提供了找到 undefined 的字段的名称。您将不得不调试您的代码以找出发生这种情况的原因。

标签: javascript angular firebase google-cloud-firestore angular8


【解决方案1】:

imageUrl 未定义,因此您遇到了该错误,在 upload 方法之后,您需要执行以下操作:

 onSubmit(form: NgForm){
    let dataa = Object.assign({},form.value);// id, imgurl, title
    delete dataa.id;
    let filepath = 'timetable'+ dataa.title;
    const fileRef = this.storage.ref(filepath);
    const task =this.storage.upload(filepath, this.selectedFile);
    task.snapshotChanges().pipe(
      finalize(() => {
        fileRef.getDownloadURL().subscribe(url => {
          console.log(url); // <-- do what ever you want with the url..
        dataa.imgurl = url;
        this.firebase.collection('timetabledata').add(dataa);
        });
      })
    ).subscribe(); 
  }

getDownloadURL() 方法不再依赖于任务,因此,为了获取 url,我们应该在存储引用之上使用 RxJS 的 finalize 方法。

查看文档:

https://github.com/angular/angularfire/blob/master/docs/storage/storage.md

【讨论】:

  • 检查imageurl是否未定义
  • 你需要和这个答案一样,复制粘贴,你需要订阅getDownloadUrl
  • 我测试了这个解决方案,它对我有用。如果答案对您有用,请考虑 accepting and/or upvoting 以便社区看到它解决了您的问题。
  • 谢谢彼得!这真的很有帮助。
猜你喜欢
  • 2021-08-29
  • 2020-08-20
  • 2021-02-26
  • 2020-06-13
  • 1970-01-01
  • 2020-06-29
  • 2019-03-08
  • 2021-08-20
相关资源
最近更新 更多