0

I'm following this tutorial to set up a chat room application in Angular and I'm having problems with setting up AngularFire2.

I noticed that in package.json file hes using 4.0.0-rc.1 so I changed mine version from "angularfire2": "^5.0.0-rc.4" to "angularfire2": "^4.0.0-rc.1"

Now my chat.service.ts imports look like this

    import { Injectable } from '@angular/core';

    import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
    import { AngularFireAuth } from 'angularfire2/auth';

    import { Observable } from 'rxjs/Observable';
    import { AuthService } from '../services/auth.service';
    import * as firebase from 'firebase/app';

    import { ChatMessage } from '../models/chat.message.model';

However I was getting the following error on the FirebaseListObservable import

chat.service.ts

When I googled this error I came across this post on github which suggests using angularfire2/database-deprecated. I did this and my project now compiles without any error. However, when I now navigate to localhost:4200/chat it redirects my app to http://localhost:4200/ and I get the following error in my console

console error

When I google this error the top result is this SO post which tells me that AngularDatabase has been separated into its own module. But I'm confused about how to fix my issue. Am I copying his entire example into my app.module.ts file? Where am I getting this AngularFireModule api key from?

I want to follow along as closely as possible with the tutorial and my app.module.ts matches exactly what the github tutorial has as well as the exact same chat.service.ts file with the exception that mine has 'angularfire2/database-deprecated' instead of 'angularfire2/database' . Where do I go from here? Here is my full app.module.ts file

    import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router';

import { AngularFireModule } from 'angularfire2';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import { AngularFireAuthModule } from 'angularfire2/auth';

import { AppComponent } from './app.component';
import { ChatFormComponent } from './chat-form/chat-form.component';
import { ChatRoomComponent } from './chat-room/chat-room.component';
import { MessagesFeedComponent } from './messages-feed/messages-feed.component';
import { MessageComponent } from './message/message.component';
import { LoginComponent } from './login/login.component';
import { SignupComponent } from './signup/signup.component';
import { NavigationComponent } from './navigation/navigation.component';
import { UserListComponent } from './user-list/user-list.component';
import { UserItemComponent } from './user-item/user-item.component';
import { ChatService } from './services/chat.service';
import { AuthService } from './services/auth.service';
import { appRoutes } from '../routes';
import { environment } from '../environments/environment';


@NgModule({
  declarations: [
    AppComponent,
    ChatFormComponent,
    ChatRoomComponent,
    MessagesFeedComponent,
    MessageComponent,
    LoginComponent,
    SignupComponent,
    NavigationComponent,
    UserListComponent,
    UserItemComponent
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot(appRoutes),
    FormsModule,
    AngularFireModule,
    AngularFireDatabaseModule,
    AngularFireAuthModule,
    AngularFireModule.initializeApp(environment.firebase)
  ],
  providers: [AuthService, ChatService],
  bootstrap: [AppComponent]
})
export class AppModule { }

and my chat service file

import { Injectable } from '@angular/core';

import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database-deprecated';
import { AngularFireAuth } from 'angularfire2/auth';

import { Observable } from 'rxjs/Observable';
import { AuthService } from '../services/auth.service';
import * as firebase from 'firebase/app';

import { ChatMessage } from '../models/chat.message.model';


@Injectable()
export class ChatService {
  user: any;
  chatMessages:FirebaseListObservable<ChatMessage[]>;
  chatMessage: ChatMessage;
  userName: Observable<string>
  constructor(
    private db: AngularFireDatabase,
    private afAuth: AngularFireAuth
  ) {
    this.afAuth.authState.subscribe(auth =>{
      if(auth !== undefined && auth !== null){
        this.user = auth;
      }
    })
   }

  sendMessage(msg: string){
    const timestamp = this.getTimeStamp();
    const email = this.user.email;
    this.chatMessages = this.getMessages();
    this.chatMessages.push({
      message: msg,
      timeSent: timestamp,
      userName: this.userName,
      email: email
    });
    console.log('called sendMessage()!');
  }

  getTimeStamp(){
    const now = new Date();
    const date = now.getUTCFullYear() + '/' + (now.getUTCMonth() + 1) + '/' + now.getUTCDate();
    const time = now.getUTCHours() + ':' + now.getUTCMinutes()  + ':' + now.getUTCSeconds();

    return (date + ' ' + time);
  }

  getMessages(): FirebaseListObservable<ChatMessage[]>{
    return this.db.list('messages', {
      query: {
        limitToLast: 25,
        orderByKey: true
      }
    })
  }
}
onTheInternet
  • 6,421
  • 10
  • 41
  • 74

2 Answers2

3

Import specifically.Import same module with the same packages. As per your code:

import { AngularFireDatabaseModule } from 'angularfire2/database';

In service you do :

import { AngularFireDatabaseModule } from 'angularfire2/database-deprecated';

AngularFireDatabaseModule imported from two other packages 'database' and 'database-deprecated' respectively.

Archit Pandey
  • 167
  • 1
  • 7
0

BE CONSISTENT IN WHAT YOU IMPORT AND WHAT YOU USE

Make sure you are importing the same Angularfire2 and Firebase package at all places. From provided snapshots it appears that in NgModule you do

import { AngularFireDatabaseModule } from 'angularfire2/database';

But in the service you do

import { AngularFireDatabaseModule } from 'angularfire2/database-deprecated';

USE THE LATEST WORKING DEPENDENCIES

Also the package.json on your GitHub repo looks as using old packages, please update.

CONSIDER OTHER OPTIONS Also, you might consider using Firestore instead od the old real-time database, but be aware, these are two different things and they require different implementation.

IDEA

Try to update your project with following dependencies in your package.json

  "dependencies": {
    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "angularfire2": "^5.0.0-rc.5-next",
    "classlist.js": "^1.1.20150312",
    "core-js": "^2.5.3",
    "firebase": "4.8.0",
    "intl": "^1.2.5",
    "rxjs": "^5.5.6",
    "web-animations-js": "^2.3.1",
    "zone.js": "^0.8.20"
  },
  "devDependencies": {
    "@angular/cli": "^1.6.4",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/jasmine": "^2.8.4",
    "@types/jasminewd2": "^2.0.3",
    "@types/node": "^9.3.0",
    "codelyzer": "^4.0.2",
    "jasmine-core": "^2.8.0",
    "jasmine-spec-reporter": "^4.2.1",
    "karma": "^2.0.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.3.3",
    "karma-jasmine": "^1.1.1",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "^5.2.2",
    "ts-node": "^4.1.0",
    "tslint": "^5.9.1",
    "typescript": "^2.6.2"
  }

Truly, the "firebase": "4.8.0" is important. The rest I added are polyfills and updates to general packages (you do not have to use them if you are not comfortable with latest unstable versions). You can just overwrite your package.json and run npm install then.

Then simply import Firebase to your main AppModule like this:

// General
import { BrowserModule           } from '@angular/platform-browser';
import { NgModule                } from '@angular/core';
import { AppComponent            } from './app.component';

// Firebase
import { AngularFireModule       } from 'angularfire2';
import { AngularFireAuthModule   } from 'angularfire2/auth';
import { AngularFirestoreModule  } from 'angularfire2/firestore';
import { environment             } from '../environments/environment';

@NgModule({
  declarations : [
               AppComponent,
               ...
             ],
  imports      : [
               BrowserModule,
               ...,
               AngularFireModule.initializeApp(environment.firebase),
               AngularFireAuthModule,
               AngularFirestoreModule,
               ...
             ],
  providers    : [ ... ],
  bootstrap    : [ AppComponent  ]
})
export class AppModule { }

Add all relevant modules from Firebase if needed (I just put Auth and Firestore to the example).

You should be able to use it in your services like this then:

import { Injectable                    } from '@angular/core';
import { AngularFirestore,
         AngularFirestoreCollection,
         AngularFirestoreDocument      } from 'angularfire2/firestore';
import * as firebase from 'firebase';

@Injectable()
export class SomeService {

  constructor( private _fireStore: AngularFirestore ) { }
               
               ... some code ...
}
Kristian
  • 501
  • 2
  • 13
  • I did this and got the same issue – onTheInternet Jan 20 '18 at 06:41
  • And it is only the FirebaseListObservable that is giving you the troubles or do you see some other issues as well? – Kristian Jan 20 '18 at 06:53
  • The only issue I see is the error in my console that I took a screen shot above. – onTheInternet Jan 20 '18 at 13:45
  • Make sure you are importing everywhere just from "angularfire2": "^5.0.0-rc.5-next" and "firebase": "4.8.0" – Kristian Jan 20 '18 at 13:55
  • When I do that I get messages saying 'cannot find name FirebaseListObservable' and 'cannot find name AngularFireDatabase' and 'cannot find name AngularFireAuth' in my chat service. Here is what the full file looks like. https://pastebin.com/Tk4BfHYd – onTheInternet Jan 20 '18 at 14:31
  • oh, sure, because you are mixing Firestore and Realtime DB altogether, but they are two distinctly different things ... in order to use Firestore, you need to change you environments references in your app, also change your logic (Firestore has specific methods) and even more, you have to switch your Firebase project from Realtime DB to Firestore ... Please, learn about Firestore at https://firebase.google.com/docs/firestore – Kristian Jan 20 '18 at 15:42
  • Have you tried just using import { AngularFireDatabaseModule } from 'angularfire2/database'; everywhere first before trying to pop in the Firestore? – Kristian Jan 20 '18 at 15:43