NullInjectorError:没有 Firestore 提供程序

问题描述 投票:0回答:1

错误 NullInjectorError:R3InjectorError(独立 [ReservarPage])[ReservasService -> ReservasService -> Firestore -> Firestore]: NullInjectorError:没有 Firestore 提供程序!

我不知道如何解决这个问题,我一直在尝试很多方法来解决这个问题,但我不能,这是我的代码

    import { Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { FormControl, FormGroup, FormsModule, Validators, ReactiveFormsModule } from '@angular/forms';
    import { IonicModule } from '@ionic/angular';
    import { RouterLink } from '@angular/router';
    import { MenuController } from '@ionic/angular';
    import { ReservasService } from '../reservas.service';

    @Component({
      selector: 'app-reservar',
      templateUrl: './reservar.page.html',
      styleUrls: ['./reservar.page.scss'],
      standalone: true,
      imports: [CommonModule, FormsModule, RouterLink, IonicModule, ReactiveFormsModule ]
    })
    export class ReservarPage  {

      reservaForm = new FormGroup({
        fechaInicio: new FormControl("", [Validators.required]),
        lugares: new FormControl("", [Validators.required]),
        puertoSalida: new FormControl("", [Validators.required]),
        noches: new FormControl("", Validators.required),
        huespedes: new FormControl("", Validators.required),
        nombreCamarote: new FormControl("", Validators.required),
        numeroCamarotes: new FormControl("", Validators.required),
        nombreCrucero: new FormControl("", Validators.required)
      })

      async onSubmit(){
        const datos = this.reservaForm.value
        await this.reservasService.guardarReserva(
          this.reservaForm.value.fechaInicio, 
          this.reservaForm.value.lugares, 
          this.reservaForm.value.puertoSalida,
          this.reservaForm.value.noches, 
          this.reservaForm.value.huespedes, 
          this.reservaForm.value.nombreCamarote, 
          this.reservaForm.value.numeroCamarotes, 
          this.reservaForm.value.nombreCrucero)
      }
  
      constructor(public menu: MenuController, public reservasService: ReservasService) { 
        this.menuActive();
      }

      menuActive(){
        this.menu.enable(true, 'menu');
      }

    }
    ```

    resrvas.service.ts:
    ```
    import { inject, Injectable } from "@angular/core";
    import { addDoc, collection, Firestore } from "@angular/fire/firestore";

    @Injectable({
        providedIn: 'root',
    })
    export class ReservasService {
        private firestore = inject(Firestore);
        constructor( ) {  }

        async guardarReserva(fechaInicio: any, lugares: any, puertoSalida: any, noches: any,
                             huespedes: any, nombreCamarote: any, numeroCamarotes: any, 
                             nombreCrucero: any) {
            const obj ={
                "fechaInicio" : fechaInicio,
                "lugares" : lugares,
                "puertoSalida" : puertoSalida,
                "noches" : noches,
                "huespedes" : huespedes,
                "nombreCamarote" : nombreCamarote,
                "numeroCamarotes" : numeroCamarotes,
                "nombreCrucero" : nombreCrucero
            };

            const Ref = collection(this.firestore, 'Reservas');

            await addDoc(Ref, obj);
        }
    }
    ```

    authentication.service.ts:
    ```
    import { inject, Injectable } from '@angular/core';
    import { Auth } from '@angular/fire/auth';
    import { createUserWithEmailAndPassword, sendPasswordResetEmail, signInWithEmailAndPassword, signOut } 
    from 'firebase/auth';
    import { User } from 'firebase/auth';

    @Injectable({
      providedIn: 'root',
    })
    export class AuthenticationService {
      private auth = inject(Auth);
      constructor(
      ) { }

      async registerUser(email: string, password:string){
        return await createUserWithEmailAndPassword(this.auth, email, password)
      }

      async loginUser(email: string, password: string){
       return await signInWithEmailAndPassword(this.auth, email,password)
      }

      async resetPassword(email: string){
        return await sendPasswordResetEmail(this.auth, email)
      }

      async signOut(){
        return await signOut(this.auth)
      }

      async getProfile():Promise <User | null> {
        return new Promise<User | null>((resolve, reject) => {
          this.auth.onAuthStateChanged(user => {
            if (user) {
              resolve(user as User);
            } else {
              resolve(null);
            }
          }, reject);
        })
      }
    }
    ```


    app.module.ts:
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { IonicModule } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app.routing.module';
import { OasisOfTheSeasPage } from './oasis-of-the-seas/oasis-of-the-seas.page';
import { environment } from 'src/environments/environment';
import { Capacitor } from '@capacitor/core';
import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, indexedDBLocalPersistence, initializeAuth, provideAuth } from '@angular/fire/auth';
import { provideFirestore, getFirestore } from '@angular/fire/firestore';
import { provideStorage, getStorage } from '@angular/fire/storage';
import { provideHttpClient } from '@angular/common/http';

@NgModule({
    imports: [BrowserModule, FormsModule, AppRoutingModule, IonicModule.forRoot({}), 
    ],
    providers: [
      provideHttpClient(),
      provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
       provideAuth(() => {
        if (Capacitor.isNativePlatform()) {
          return initializeAuth(getApp(), {
            persistence: indexedDBLocalPersistence
          });
        } else {
          return getAuth();
        }
      }),
      //getAuth()),
      provideFirestore(() => getFirestore()),
      provideStorage(() => getStorage()),
    ],
    declarations: [AppComponent, OasisOfTheSeasPage],
    bootstrap: [AppComponent],
  })
  export class AppModule {}

reservar.page.html:
<ion-header>
  <ion-toolbar color="primary">
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>Reservar</ion-title>
  </ion-toolbar>
</ion-header>
<ion-content>
  <form [formGroup]="reservaForm" (ngSubmit)="onSubmit()">
    <ion-item class="titulo" color="primary">
      <ion-title>Fecha de Inicio del Crucero</ion-title>
    </ion-item>
    <ion-datetime-button class="fecha" datetime="datetime" name="fechaInicio" formName="fechaInicio">    </ion-datetime-button>
    <ion-modal [keepContentsMounted]="true">
      <ng-template>
        <ion-datetime id="datetime"></ion-datetime>
      </ng-template>
    </ion-modal>
    <ion-item class="titulo" color="primary">
      <ion-title>Lugares para visitar</ion-title>
    </ion-item>
    <ion-item>
      <ion-select label="Lugares para visitar:" placeholder="Que lugares quieres visitar" name="lugares" formControlName="lugares">
        <ion-select-option value="alaska">Alaska</ion-select-option>
        <ion-select-option value="asia">Asia</ion-select-option>
        <ion-select-option value="australia&nuevazelanda">Australia y Nueva Zelanda</ion-select-option>
        <ion-select-option value="canada&nuevainglaterra">Canada y Nueva Inglaterra</ion-select-option>
        <ion-select-option value="canaldepanama">Canal de Panamá</ion-select-option>
        <ion-select-option value="caribe">El Caribe</ion-select-option>
        <ion-select-option value="europa">Europa</ion-select-option>
        <ion-select-option value="hawai">Hawái</ion-select-option>
        <ion-select-option value="bahamas">Las Bahamas</ion-select-option>
        <ion-select-option value="mexico">México</ion-select-option>
        <ion-select-option value="pacificonoroeste">Pacífico Noroeste</ion-select-option>
        <ion-select-option value="pacificosur">Pacífico Sur</ion-select-option>
        <ion-select-option value="transatlantico">Transatlántico</ion-select-option>
        <ion-select-option value="transpacifico">Transpacífico</ion-select-option>
      </ion-select>
    </ion-item>
    <ion-item class="titulo" color="primary">
      <ion-title>Escoge el puerto de salida</ion-title>
    </ion-item>
    <ion-item>
      <ion-select label="Puerto de Salida:" placeholder="Escoge el puerto de salida" name="puertoSalida" formControlName="puertoSalida">
        <ion-select-option value="barcelona">Barcelona, España</ion-select-option>
        <ion-select-option value="roma">Roma (Civitavecchia), Italia</ion-select-option>
        <ion-select-option value="ravena">Rávena (Venecia), Italia</ion-select-option>
        <ion-select-option value="southampton">Southampton, Inglaterra</ion-select-option>
        <ion-select-option value="baltimore">Baltimore, Maryland</ion-select-option>
        <ion-select-option value="boston">Boston, Massachusetts</ion-select-option>
        <ion-select-option value="capeLiberty">Cape Liberty (Nueva York), Nueva Jersey</ion-select-option>
        <ion-select-option value="fortLauderdale">Fort Lauderdale, Florida</ion-select-option>
        <ion-select-option value="galveston">Galveston, Texas</ion-select-option>
        <ion-select-option value="losAngeles">Los Ángeles, California</ion-select-option>
        <ion-select-option value="miami">Miami, Florida</ion-select-option>
        <ion-select-option value="nuevaOrleans">Nueva Orleans, Luisiana</ion-select-option>
        <ion-select-option value="oahu">Oahu (Honolulú), Hawái</ion-select-option>
        <ion-select-option value="orlando">Orlando (Puerto Cañaveral), Florida</ion-select-option>
        <ion-select-option value="vancouver">Puerto de cruceros de Vancouver, (Columbia Británica)</ion-select-option>
        <ion-select-option value="sanDiego">San Diego, California</ion-select-option>
        <ion-select-option value="seattle">Seattle, Washington</ion-select-option>
        <ion-select-option value="seward">Seward, Alaska</ion-select-option>
        <ion-select-option value="tampa">Tampa, Florida</ion-select-option>
        <ion-select-option value="cartagena">Cartagena, Colombia</ion-select-option>
        <ion-select-option value="colon">Colón, Panamá</ion-select-option>
        <ion-select-option value="sanJuan">San Juan, Puerto Rico</ion-select-option>
        <ion-select-option value="brisbane">Brisbane, Australia</ion-select-option>
        <ion-select-option value="sidney">Sídney, Australia</ion-select-option>
      </ion-select>
    </ion-item>
    <ion-item class="titulo" color="primary">
      <ion-title>Cantidad de noches</ion-title>
    </ion-item>
    <ion-item>
      <ion-input label="Número de huéspedes:" placeholder="Escoge el número de huéspedes" name="huespedes" formName="huespedes"></ion-input>
    </ion-item>
    <div style="text-align: center">Cada 4 huéspedes puedes pedir otro camarote</div>
    <ion-item class="titulo" color="primary">
      <ion-title>Camarotes</ion-title>
    </ion-item>
    <ion-item>
      <ion-select label="Camarote:" placeholder="Escoge un camarote" name="nombreCamarote" formName="nombreCamarote">
        <ion-select-option value="camarotesInteriores">Camarotes Interiores</ion-select-option>
        <ion-select-option value="vistaOceano">Vista al Océano</ion-select-option>
        <ion-select-option value="camaroteBalcon">Camarotes con Balcón</ion-select-option>
        <ion-select-option value="sunsetCornerSuite">Sunser Corner Suite</ion-select-option>
        <ion-select-option value="panoramicSuite">Panoramic Suite</ion-select-option>
        <ion-select-option value="infinityBalconies">Infinity Balconies</ion-select-option>
      </ion-select>
    </ion-item>
    <ion-item class="titulo" color="primary">
      <ion-title>Número de Camarotes</ion-title>
    </ion-item>
    <ion-item>
      <ion-input label="Número de camarotes:" placeholder="Escoge el número de camarotes" name="numeroCamarotes" formName="numeroCamarotes"></ion-input>
    </ion-item>
    <ion-item class="titulo" color="primary">
      <ion-title>Nuestra Flota</ion-title>
    </ion-item>
    <ion-item>
      <ion-select label="Crucero:" placeholder="Escoge un crucero" name="nombreCrucero" formName="nombreCrucero">
        <ion-select-option value="adventure-of-the-seas">Adventure of the Seas</ion-select-option>
        <ion-select-option value="allure-of-the-seas">Allure of the Seas</ion-select-option>
        <ion-select-option value="anthem-of-the-seas">Anthem of the Seas</ion-select-option>
        <ion-select-option value="brilliance-of-the-seas">Brilliance of the Seas</ion-select-option>
        <ion-select-option value="enchantment-of-the-seas">Enchantment of the Seas</ion-select-option>
        <ion-select-option value="explorer-of-the-seas">Explorer of the Seas</ion-select-option>
        <ion-select-option value="freedom-of-the-seas">Freedom of the Seas</ion-select-option>
        <ion-select-option value="grandeur-of-the-seas">Grandeur of the Seas</ion-select-option>
        <ion-select-option value="harmony-of-the-seas">Harmony of the Seas</ion-select-option>
        <ion-select-option value="icon-of-the-seas">Icon of the Seas</ion-select-option>
        <ion-select-option value="independence-of-the-seas">Independence of the Seas</ion-select-option>
        <ion-select-option value="jewel-of-the-seas">Jewel of the Seas</ion-select-option>
        <ion-select-option value="liberty-of-the-seas">Liberty of the Seas</ion-select-option>
        <ion-select-option value="mariner-of-the-seas">Mariner of the Seas</ion-select-option>
        <ion-select-option value="navigator-of-the-seas">Navigator of the Seas</ion-select-option>
        <ion-select-option value="oasis-of-the-seas">Oasis of the Seas</ion-select-option>
        <ion-select-option value="odyssey-of-the-seas">Odyssey of the Seas</ion-select-option>
        <ion-select-option value="ovation-of-the-seas">Ovation of the Seas</ion-select-option>
        <ion-select-option value="quantum-of-the-seas">Quantum of the Seas</ion-select-option>
        <ion-select-option value="radiance-of-the-seas">Radiance of the Seas</ion-select-option>
        <ion-select-option value="rhapsody-of-the-seas">Rhapsody of the Seas</ion-select-option>
        <ion-select-option value="serenade-of-the-seas">Serenade of the Seas</ion-select-option>
        <ion-select-option value="spectrum-of-the-seas">Spectrum of the Seas</ion-select-option>
        <ion-select-option value="star-of-the-seas">Star of the Seas</ion-select-option>
        <ion-select-option value="symphony-of-the-seas">Symphony of the Seas</ion-select-option>
        <ion-select-option value="utopia-of-the-seas">Utopia of the Seas</ion-select-option>
        <ion-select-option value="vision-of-the-seas">Vision of the Seas</ion-select-option>
        <ion-select-option value="voyager-of-the-seas">Voyager of the Seas</ion-select-option>
        <ion-select-option value="wonder-of-the-seas">Wonder of the Seas</ion-select-option>
      </ion-select>
    </ion-item>
    <div class="boton">
      <ion-button type="submit">Reservar</ion-button>
    </div>
  </form>
</ion-content>


I expect that when i press reservar button it saves all the data in firebase
angular firebase ionic-framework
1个回答
0
投票

确保您没有将

ReservasService
添加到任何延迟加载模块的提供程序数组或应用程序中的任何位置,这可能是问题所在。

ReservasService
应在
root
中提供,并且不应有任何其他实例,这些实例将无法访问
Firestore
提供程序。

© www.soinside.com 2019 - 2024. All rights reserved.