import 'rxjs/add/observable/merge' ; import 'rxjs/add/operator/switchMap' ; import { Injectable } from '@angular/core' ; import { AngularFireDatabase , AngularFireList } from 'angularfire2/database' ; import { AuthService } from '../auth/auth.service' ; import { Message , Room , User } from './data.model' ; import { Observable } from 'rxjs/Observable' ; import { BehaviorSubject } from 'rxjs/BehaviorSubject' ; import * as firebase from 'firebase' ; @ Injectable ( ) export class RtdbService { private moderatorsPath : string ; private roomMessagesPath : string ; private roomMetadataPath : string ; private roomUsersPath : string ; private suspensionsPath : string ; private userNamesOnlinePath : string ; private usersPath : string ; private roomsRef : AngularFireList < Room > ; private usersRef : AngularFireList < User > ; constructor ( private afd , private auth ) { this . moderatorsPath = '/moderators' ; this . roomMessagesPath = '/room-messages' ; this . roomMetadataPath = '/room-metadata' ; this . roomUsersPath = '/room-users' ; this . suspensionsPath = '/suspensions' ; this . userNamesOnlinePath = '/user-names-online' ; this . usersPath = '/users' ; this . roomsRef = this . afd . list ( this . roomMetadataPath ) ; this . usersRef = this . afd . list ( this . usersPath ) ; } /** USERS **/ async createUser ( user ) { const promise = this . afd . list ( this . usersPath ) . push ( { } ) ; let newUserId ; await promise . then ( result => { user . id = newUserId = result . key ; this . usersRef . set ( user . id , user ) ; } , err => console . error ( err , 'You do not have access!' ) ) ; return newUserId ; } getUser ( userId ) { const userPath = `${ this . usersPath }/${ userId }` ; return this . afd . object ( userPath ) . snapshotChanges ( ) . map ( action => { return { ... action . payload . val ( ) } ; } ) ; } removeUser ( user ) { return this . usersRef . remove ( user . id ) ; } updateUser ( user ) { return this . usersRef . update ( user . id , user ) ; } /** ROOM METADATA **/ getRooms ( ) { return this . roomsRef . snapshotChanges ( ) . map ( changes => { return changes . map ( c => ( { ... c . payload . val ( ) } ) ) ; } ) ; } async createRoom ( room ) { const promise = this . roomsRef . push ( { } ) ; let newRoomId ; room . createdAt = firebase . database . ServerValue . TIMESTAMP ; room . createdByUserId = this . auth . id ; room . authorizedUsers = { } ; room . authorizedUsers [ this . auth . id ] = true ; await promise . then ( result => { room . id = newRoomId = result . key ; this . roomsRef . set ( room . id , room ) ; } , err => console . error ( err , 'You do not have access!' ) ) ; return newRoomId ; } getRoom ( roomId ) { const roomPath = `${ this . roomMetadataPath }/${ roomId }` ; return this . afd . object ( roomPath ) . snapshotChanges ( ) . map ( action => { return { ... action . payload . val ( ) } ; } ) ; } removeRoom ( room ) { return this . roomsRef . remove ( room . id ) ; } updateRoom ( room , changes ) { return this . roomsRef . update ( room . id , changes ) ; } /** ROOM MESSAGES **/ async createRoomMessage ( roomId , message ) { const messagePath = `${ this . roomMessagesPath }/${ roomId }/SOURCE` ; let newMessageId ; message . timestamp = firebase . database . ServerValue . TIMESTAMP ; const promise = this . afd . list ( messagePath ) . push ( { } ) ; await promise . then ( result => { message . id = newMessageId = result . key ; this . afd . list ( messagePath ) . set ( message . id , message ) ; } , err => console . error ( err , 'You do not have access!' ) ) ; return newMessageId ; } getRoomMessages ( roomId ) { return this . afd . list ( `${ this . roomMessagesPath }/${ roomId }/OUTPUT` ) ; } getRoomMessagesByQuery ( roomId , subject$ ) { return subject$ . switchMap ( subject => { return this . afd . list ( `${ this . roomMessagesPath }/${ roomId }/OUTPUT` , ref => subject ? ref . orderByChild ( 'language' ) . equalTo ( subject ) : ref ) . snapshotChanges ( ) . map ( changes => { return changes . map ( c => ( { ... c . payload . val ( ) } ) ) ; } ) ; } ) ; } removeRoomMessage ( roomId , message ) { return this . afd . list ( `${ this . roomMessagesPath }/${ roomId }/SOURCE` ) . remove ( message . id ) ; } updateRoomMessage ( roomId , message , changes ) { return this . afd . list ( `${ this . roomMessagesPath }/${ roomId }/SOURCE` ) . update ( message . id , changes ) ; } deleteRoomMessages ( roomId ) { return this . afd . list ( `${ this . roomMessagesPath }/${ roomId }/SOURCE` ) . remove ( ) ; } /** ROOM USERS **/ createRoomUser ( roomId , user ) { return this . afd . list ( `${ this . roomUsersPath }/${ roomId }` ) . set ( user . id , user ) ; } getRoomUsers ( roomId ) { return this . afd . list ( `${ this . roomUsersPath }/${ roomId }` ) . snapshotChanges ( ) . map ( changes => { return changes . map ( c => ( { ... c . payload . val ( ) } ) ) ; } ) ; } removeRoomUser ( roomId , user ) { return this . afd . list ( `${ this . roomUsersPath }/${ roomId }` ) . remove ( user . id ) ; } updateRoomUser ( roomId , user , changes ) { return this . afd . list ( `${ this . roomUsersPath }/${ roomId }` ) . update ( user . id , changes ) ; } private loadUserMetadata ( onComplete ) { } private setupDataEvents ( ) { } private addEventCallback ( eventId , callback ) { } private getEventCallbacks ( eventId ) { } private invokeEventCallbacks ( eventId ) { } private queuePresenceOperation ( ref , onlineValue , offlineValue ) { } private removePresenceOperation ( ref , value ) { } private onUpdateUser ( snapshot ) { } private onAuthRequired ( ) { } private onEnterRoom ( room ) { } private onNewMessage ( roomId , snapshot ) { } private onRemoveMessage ( roomId , snapshot ) { } private onLeaveRoom ( roomId ) { } private onNotification ( snapshot ) { } private onFirechatInvite ( snapshot ) { } private onFirechatInviteResponse ( snapshot ) { } public setUser ( userId , userName , callback ) { } public resumeSession ( ) { } public on ( eventType , cb ) { } public enterRoom ( roomId ) { } public leaveRoom ( roomId ) { } public sendMessage ( roomId , messageContent , messageType , cb ) { } public deleteMessage ( roomId , messageId , cb ) { } public toggleUserMute ( userId , cb ) { } public sendSuperuserNotification ( userId , notificationType , data , cb ) { } public warnUser ( userId ) { } public suspendUser ( userId , timeLengthSeconds , cb ) { } public inviteUser ( userId , roomId ) { } public acceptInvite ( inviteId , cb ) { } public declineInvite ( inviteId , cb ) { } public getRoomList ( cb ) { } public getUsersByRoom ( ) { } public getUsersByPrefix ( prefix , startAt , endAt , limit , cb ) { } public userIsModerator ( ) { } public warn ( msg ) { } }