Hola a Todos.
Estoy desarrollando una aplicación ionic en la cual busco consumir notificaciones por medio de firebase pero con un backend utilizando node.js y mongoDB, al ejecutar el programa en dispositivo físico me sale el siguiente error:
Failed to load resource: net::ERR_EMPTY_RESPONSE
ERROR HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: "http://192.XXX.X.XX:3800/api/saveNoti", ok: false, …}
defaultErrorLogger @ vendor.js:51847
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ vendor.js:51895
next @ vendor.js:53894
schedulerFn @ vendor.js:49638
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ vendor.js:129523
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ vendor.js:129461
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ vendor.js:129407
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ vendor.js:129384
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ vendor.js:129150
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ vendor.js:49622
(anonymous) @ vendor.js:53444
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ polyfills.js:2753
push../node_modules/zone.js/dist/zone.js.Zone.run @ polyfills.js:2512
push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular @ vendor.js:53381
onHandleError @ vendor.js:53444
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ polyfills.js:2757
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ polyfills.js:2560
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ polyfills.js:2860
ZoneTask.invoke @ polyfills.js:2849
timer @ polyfills.js:4643
setTimeout (async)
scheduleTask @ polyfills.js:4664
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ polyfills.js:2772
onScheduleTask @ polyfills.js:2663
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ polyfills.js:2766
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ polyfills.js:2600
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMacroTask @ polyfills.js:2623
scheduleMacroTaskWithCurrentZone @ polyfills.js:3607
(anonymous) @ polyfills.js:4679
proto.<computed> @ polyfills.js:3931
hostReportError @ vendor.js:139645
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.error @ vendor.js:129495
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error @ vendor.js:129410
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ vendor.js:129390
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error @ vendor.js:129410
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ vendor.js:129390
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error @ vendor.js:129410
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ vendor.js:129390
push../node_modules/rxjs/_esm5/internal/OuterSubscriber.js.OuterSubscriber.notifyError @ vendor.js:128901
push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._error @ vendor.js:128600
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error @ vendor.js:129390
onError @ vendor.js:7985
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ polyfills.js:2785
onInvokeTask @ vendor.js:53413
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask @ polyfills.js:2784
push../node_modules/zone.js/dist/zone.js.Zone.runTask @ polyfills.js:2557
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ polyfills.js:2860
invokeTask @ polyfills.js:4106
globalZoneAwareCallback @ polyfills.js:4132
Este es el codigo que estoy utilizando.
Mi backend:
Controlador:
import {Response} from 'express';
import Notification from '../modelos/notifications';
function notification(req: any, res:Response){
console.log('Respuesta del req', req.body );
Notification.find('tokens').insertOne( req.body, ((err: any, body: any ) => {
if (err) throw console.log('Error al encontrar el token', err);
console.log('Información de los datos obtenidos', body)
res.status(200).send('');
}));
}
var FCM = require('fcm-node');
// Se coloca la clave derl servidor del Firebase
var serverKey = 'XXXXXXXXX';
var fcm = new FCM(serverKey);
function send(req: any, res:Response) {
// Obtener el token del cuerpo
const params = req.body;
var tokens = new Notification();
try {
Notification.create( tokens ).then( async tokenNoti => {
res.status(200).json({ok: true,
notificacion: tokenNoti
});
}).catch( err => {
res.json(err)
});
} catch (error) {
console.log('Error al guardar token', error);
}
}
export default {notification, send}
Rutas
import express from 'express';
import Notification from '../controllers/notification';
const api = express.Router();
// Obtener datos y envio
api.post('/notificacion', Notification.notification);
api.post('/saveNoti', Notification.send);
export default api;
Modelo
Import mongoose, { Schema, Document } from 'mongoose';
export interface INotification extends Document {
notification: string;
}
const NotificationSchema: Schema = new Schema ({
tokens: { type: String },
created_at: { type: Date, default: Date.now()}
});
export default mongoose.model<INotification>('Notification', NotificationSchema);
Frontend:
En el app.component.ts
import { Component } from '@angular/core';
import { Platform, ToastController } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { TabsPage } from '../app/pages/tabs/tabs.page';
import { FcmProvider } from '../app/provider/fcm.service';
import { tap } from 'rxjs/operators';
import { Firebase } from '@ionic-native/firebase/ngx';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
rootPage: any = TabsPage;
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
public fcm: FcmProvider,
public toastCtrl: ToastController,
public firebase: Firebase ) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
const devicePlatform = this.platform.is('android') ? 'android' : 'ios';
if ( devicePlatform ) {
this.fcm.getToken();
this.fcm.listenToNotifications().pipe(
tap(async msg => {
const toast = await this.toastCtrl.create({
message: msg.body,
duration: 3000
});
toast.present();
})
)
.subscribe();
}
});
}
}
Se crea una carpeta con el servicio del fcm la cual hará la acción
import { Firebase } from '@ionic-native/firebase/ngx';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';
// Creamos y llamamos el pedazo de la URL
const URL = environment.url;
@Injectable({
providedIn: 'root'
})
export class FcmProvider {
firebaseToken: string;
constructor(private platform: Platform,
public firebase: Firebase,
public http: HttpClient,
public navCtrl: NavController) {
console.log('Desde las notificaciones');
}
async getToken() {
let token;
if (this.platform.is('android')) {
token = await this.firebase.getToken();
}
if (this.platform.is('ios')) {
token = await this.firebase.getToken();
await this.firebase.grantPermission();
}
// Publique el token en su servidor de node
this.http.post(`${ URL }/api/saveNoti`, token)
.subscribe(data => {
console.log(JSON.stringify(data));
console.log('Respuesta de los datos', data);
}, error => {
console.log('err', error);
console.log(JSON.stringify(error));
});
}
// Escuche los mensajes entrantes de FCM.
listenToNotifications() {
return this.firebase.onNotificationOpen();
}
}
Agradezco si me puedes orientar.
Gracias por tu colaboración.
Saludos.