Firebase.child失败:第一个参数isError:Firebase.child失败:第一个参数是无效路径:“null”

时间:2017-04-16 15:58:50

标签: firebase firebase-realtime-database ionic2 firebase-authentication firebase-storage

这是电影列表的代码。

用户可以使用图片将电影添加到数据库中。用户可以编辑或删除电影。上传和检索没有问题

当我尝试编辑或删除电影时,会显示错误。

请帮忙。     Firebase,离子,cordova和角度使用。当我尝试编辑或删除一个     请帮助解决问题。      如果有人能解释,也会很高兴     他们的答案也是。谢谢!

modals.ts和home.ts拥有大部分代码。所以我认为错误是     那里。

modals.ts

        import { Component } from '@angular/core';
        import { FormBuilder, FormGroup, Validators } from '@angular/forms';
        import { NavController, ViewController, NavParams } from 'ionic-
        angular';
        import { Image } from '../../providers/image';
        import { Preloader } from '../../providers/preloader';
        import { Database } from '../../providers/database';
        import * as firebase from 'firebase';

    @Component({
      selector: 'page-modals',
      templateUrl: 'modals.html'
    })
    export class ModalsPage {

       public form             : any;
       public filmImage        : any;
       public movies           : any;
       public movieName        : any     = '';
       public movieImage       : any     = '';
       public movieGenres      : any     = [];
       public movieDuration    : any     = '';
       public movieSummary     : any     = '';
       public movieActors      : any     = [];
       public movieYear        : any     = '';
       public movieRating      : any     = '';
       public movieId          : string  = '';
       public isEditable       : boolean = false;


       constructor(
          public navCtrl        : NavController,
          public params         : NavParams,
          private _FB           : FormBuilder,
          private _IMG          : Image,
          public viewCtrl       : ViewController,
          private _LOADER       : Preloader,
          private _DB           : Database
       )
       {
          this.form         = _FB.group({
             'summary'      : ['', Validators.minLength(10)],
             'year'         : ['', Validators.maxLength(4)],
             'name'         : ['', Validators.required],
             'duration'     : ['', Validators.required],
             'image'        : ['', Validators.required],
             'rating'       : ['', Validators.required],
             'genres'       : ['', Validators.required],
             'actors'       : ['', Validators.required]
          });

          this.movies = firebase.database().ref('films/');


          if(params.get('isEdited'))
          {
              let movie             = params.get('movie'),
                  k;

              this.movieName        = movie.title;
              this.movieDuration    = movie.duration;
              this.movieSummary     = movie.summary;
              this.movieRating      = movie.rating;
              this.movieYear        = movie.year;
              this.movieImage       = movie.image;
              this.filmImage        = movie.image;
              this.movieId          = movie.id;


              for(k in movie.genres)
              {
                 this.movieGenres.push(movie.genres[k].name);
              }


              for(k in movie.actors)
              {
                 this.movieActors.push(movie.actors[k].name);
              }

              this.isEditable      = true;
          }
       }




       saveMovie(val)
       {
          this._LOADER.displayPreloader();

          let title     : string        = this.form.controls["name"].value,
              summary   : string        = this.form.controls["summary"].value,
              rating    : number        = this.form.controls["rating"].value,
              genres    : any           = this.form.controls["genres"].value,
              actors    : any           = this.form.controls["actors"].value,
              duration  : string        = this.form.controls["duration"].value,
              year      : string        = this.form.controls["year"].value,
              image     : string        = this.filmImage,
              types     : any           = [],
              people    : any           = [],
              k         : any;


          for(k in genres)
          {
             types.push({
                "name" : genres[k]
             });
          }


          for(k in actors)
          {
             people.push({
                "name" : actors[k]
             });
          }


          if(this.isEditable)
          {

             if(image !== this.movieImage)
             {
                this._DB.uploadImage(image)
                .then((snapshot : any) =>
                {
                   let uploadedImage : any = snapshot.downloadURL;

                   this._DB.updateDatabase(this.movieId,
                   {
                      title    : title,
                      summary  : summary,
                      rating   : rating,
                      duration : duration,
                      image    : uploadedImage,
                      genres   : types,
                      actors   : people,
                      year     : year
                   })
                   .then((data) =>
                   {
                      this._LOADER.hidePreloader();
                   });

                });
             }
             else
             {

               this._DB.updateDatabase(this.movieId,
               {
                  title    : title,
                  summary  : summary,
                  rating   : rating,
                  duration : duration,
                  genres   : types,
                  actors   : people,
                  year     : year
               })
               .then((data) =>
               {
                  this._LOADER.hidePreloader();
               });
             }

          }
          else
          {
             this._DB.uploadImage(image)
             .then((snapshot : any) =>
             {
                let uploadedImage : any = snapshot.downloadURL;

                this._DB.addToDatabase({
                   title    : title,
                   image    : uploadedImage,
                   summary  : summary,
                   rating   : rating,
                   duration : duration,
                   genres   : types,
                   actors   : people,
                   year     : year
                })
                .then((data) =>
                {
                   this._LOADER.hidePreloader();
                });
             });

          }
          this.closeModal(true);
       }



       closeModal(val = null)
       {
          this.viewCtrl.dismiss(val);
       }



       selectImage()
       {
          this._IMG.selectImage()
          .then((data) =>
          {
             this.filmImage = data;
          });
       }



    }

那是modals.ts,还有modals.html

home.ts

import { Component } from '@angular/core';
import { NavController, Platform, ModalController } from 'ionic-angular';
import { ModalsPage } from '../../pages/modals/modals';
import { Image } from '../../providers/image';
import { Preloader } from '../../providers/preloader';
import { Database } from '../../providers/database';
import * as firebase from 'firebase';
import { Http } from '@angular/http';
import 'rxjs/Rx';


@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

   private auth     : any;
   public movies    : any;
   private email    : string = 'che@gmail.com';
   private pass     : string = 'che123';


   constructor( public navCtrl       : NavController,
                private platform     : Platform,
                private modalCtrl    : ModalController,
                private _IMG         : Image,
                private _LOADER      : Preloader,
                private _DB          : Database)
   {
   }


   ionViewDidEnter()
   {
      this._LOADER.displayPreloader();
      this.platform.ready()
      .then(() =>
      {
         firebase.auth().signInWithEmailAndPassword(this.email, this.pass)
         .then((credentials) =>
         {
            this.loadAndParseMovies();
         })
         .catch((err : Error) =>
         {
            console.log(err.message);
         });
      });
   }


   loadAndParseMovies()
   {
      this.movies = this._DB.renderMovies();
      this._LOADER.hidePreloader();
   }


   addRecord()
   {
      let modal = this.modalCtrl.create(ModalsPage);
      modal.onDidDismiss((data) =>
      {
         if(data)
         {
            this._LOADER.displayPreloader();
            this.loadAndParseMovies();
         }
      });
      modal.present();
   }


   editMovie(movie)
   {
      let params = { movie: movie, isEdited: true },
          modal  = this.modalCtrl.create(ModalsPage, params);

      modal.onDidDismiss((data) =>
      {
         if(data)
         {
            this._LOADER.displayPreloader();
            this.loadAndParseMovies();
         }
      });
      modal.present();
   }



   deleteMovie(movie)
   {
      this._LOADER.displayPreloader();

      this._DB.deleteMovie(movie.id)
      .then((data) =>
      {
         this.loadAndParseMovies();
      });
   }


}

MydatabaseStructure

Firebase

Home.html中

 <ion-header>
   <ion-navbar>
      <ion-title>
         Moveez
      </ion-title>
      <ion-buttons end>
       <button
          ion-button
          icon-only
          (click)="addRecord()">
      <ion-icon name="add"></ion-icon>
       </button>
    </ion-buttons>
   </ion-navbar>
</ion-header>

<ion-content padding>
  <ion-refresher (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>

   <ion-list>
      <ion-card
         class="movie"
         text-wrap
         *ngFor="let movie of movies | async">
         <ion-item>
            <div *ngIf="movie.image">
               <img [src]="movie.image">
            </div>
            <h2>{{ movie.title }}</h2>
            <small>{{ movie.date }} ({{ movie.duration }})</small>
            <p>{{ movie.summary }}</p>

            <section class="multiples">
               <h3>Actors/Actresses</h3>
             <ion-chip
                *ngFor="let actor of movie.actors"
                padding-left
                padding-right
                margin-right>{{ actor.name }}</ion-chip>
            </section>


            <section class="multiples">
               <h3>Genres</h3>
               <ion-chip
                  *ngFor="let genre of movie.genres"
                  padding-left
                  padding-right
                  margin-right>{{ genre.name }}</ion-chip>
            </section>

         </ion-item>


         <div class="manage-record" padding>
           <button
              ion-button
              text-center
              color="primary"
              (click)="editMovie(movie)">Edit</button>

           <button
              ion-button
              text-center
              color="danger"
              (click)="deleteMovie(movie)">Delete</button>
       </div>

      </ion-card>
   </ion-list>


</ion-content>



**modals.html**
    <ion-header>
       <ion-toolbar>
          <ion-title>
             {{ title }}
          </ion-title>
          <ion-buttons start>
             <button
                ion-button
                (click)="closeModal()">
               <span
                  ion-text
                  color="primary"
                  showWhen="ios">Cancel</span>
               <ion-icon
                  name="md-close"
                  showWhen="android,windows"></ion-icon>
             </button>
          </ion-buttons>
       </ion-toolbar>
    </ion-header>
    <ion-content>
       <form
          [formGroup]="form"
          (ngSubmit)="saveMovie(form.value)">
          <ion-item-divider color="light">
             <div *ngIf="!isEditable">
                Add a new movie
             </div>
             <div *ngIf="isEditable">
                Amend this movie
             </div>
          </ion-item-divider>
          <ion-item>
             <ion-label stacked>Movie name:</ion-label>
             <ion-input
                type="text"
                formControlName="name"
                [(ngModel)]="movieName"></ion-input>
          </ion-item>
          <ion-item>
             <span
                ion-text
                color="danger"
                block
                text-center
                padding-top
                padding-bottom
                (click)="selectImage()">Select an image</span>
                <input
                   type="hidden"
                   name="image"
                   formControlName="image"
                   [(ngModel)]="filmImage">
                <img [src]="filmImage">
          </ion-item>
          <ion-item>
             <ion-label stacked>Movie length:</ion-label>
             <ion-input
                type="text"
                formControlName="duration"
                [(ngModel)]="movieDuration"></ion-input>
          </ion-item>
          <ion-item>
             <ion-label stacked>Genre:</ion-label>
             <ion-select
                formControlName="genres"
                multiple="true"
                [(ngModel)]="movieGenres">
                 <ion-option value="Action">Action</ion-option>
                 <ion-option value="Comedy">Comedy</ion-option>
                 <ion-option value="Documentary">Documentary</ion-option>
                 <ion-option value="Historical">Historical</ion-option>
                 <ion-option value="Romance">Romance</ion-option>
                 <ion-option value="Science Fiction">Science Fiction</ion-option>
                 <ion-option value="Thriller">Thriller</ion-option>
                 <ion-option value="Zombie">Zombie</ion-option>
                 <ion-option value="War">War</ion-option>
             </ion-select>
          </ion-item>
          <ion-item>
             <ion-label stacked>Actors/actresses:</ion-label>
             <ion-select
                formControlName="actors"
                multiple="true"
                [(ngModel)]="movieActors">
                 <ion-option value="Keanu Reeves">Keanu Reeves</ion-option>
                 <ion-option value="Ian McShane">Ian McShane</ion-option>
                 <ion-option value="Adrianne Palicki">Adrianne Palicki</ion-option>
                 <ion-option value="Woody Harrelson">Woody Harrelson</ion-option>
                 <ion-option value="Willem Dafoe">Willem Dafoe</ion-option>
                 <ion-option value="John Leguizamo">John Leguizamo</ion-option>
                 <ion-option value="Michael Nyqvist">Michael Nyqvist</ion-option>
                 <ion-option value="Bridget Moynahan">Bridget Moynahan</ion-option>
                 <ion-option value="Alfie Allen">Alfie Allen</ion-option>
                 <ion-option value="Russell Crowe">Russell Crowe</ion-option>
                 <ion-option value="Oliver Reed">Oliver Reed</ion-option>
                 <ion-option value="Joaquin Phoenix">Joaquin Phoenix</ion-option>
                 <ion-option value="Connie Nielsen">Connie Nielsen</ion-option>
                 <ion-option value="Ralf Moeller">Ralf Moeller</ion-option>
                 <ion-option value="Tom Hanks">Tom Hanks</ion-option>
                 <ion-option value="Leonardo Dicaprio">Leonardo Dicaprio</ion-option>
                 <ion-option value="Christopher Walken">Christopher Walken</ion-option>
                 <ion-option value="Mike Myers">Mike Myers</ion-option>
                 <ion-option value="Heather Graham">Heather Graham</ion-option>
                 <ion-option value="Verne Troyer">Verne Troyer</ion-option>
                 <ion-option value="Robert Wagner">Robert Wagner</ion-option>
                 <ion-option value="Rob Lowe">Rob Lowe</ion-option>
                 <ion-option value="Mindy Sterling">Mindy Sterling</ion-option>
             </ion-select>
          </ion-item>
          <ion-item>
             <ion-label stacked>Summary:</ion-label>
             <ion-textarea
                rows="6"
                formControlName="summary"
                [(ngModel)]="movieSummary"></ion-textarea>
          </ion-item>
          <ion-item>
             <ion-label stacked>Film rating:</ion-label>
             <ion-select
                formControlName="rating"
                [(ngModel)]="movieRating">
                 <ion-option value="PG">PG</ion-option>
                 <ion-option value="12">12</ion-option>
                 <ion-option value="12A">12A</ion-option>
                 <ion-option value="15">15</ion-option>
                 <ion-option value="18">18</ion-option>
                 <ion-option value="U">U</ion-option>
                 <ion-option value="R18">R18</ion-option>
             </ion-select>
          </ion-item>
          <ion-item>
             <ion-label stacked>Year released:</ion-label>
             <ion-input
                type="text"
                formControlName="year"
                [(ngModel)]="movieYear"></ion-input>
          </ion-item>
          <ion-item>
             <input
                type="hidden"
                name="movieId">
             <button
               ion-button
               block
               color="primary"
               text-center
               padding-top
               padding-bottom
               [disabled]="!form.valid">
                <div *ngIf="!isEditable">
                   Add a new movie
                </div>
                <div *ngIf="isEditable">
                   Update this movie
                </div>
                </button>
          </ion-item>
       </form>
    </ion-content>

1 个答案:

答案 0 :(得分:0)

您在saveMovie(val)函数中犯了一个简单错误。在javascript / typescript中使用for..in构造时,您将获得每个值而不是索引。

 for(k in genres)
          {
             types.push({
               // "name" : genres[k] change it
               "name" : k
             });
          }


          for(k in actors)
          {
             people.push({
                "name" : k
             });
          }

根据html,它们都将包含一个字符串数组......