hino / app / services / fcm.js
fcm.js
Raw
import Service from '@ember/service';
import subscribe from 'ember-cordova-events/utils/subscribe';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default Service.extend({
	fcmTokenData: service(),
	sessionAccount: service(),
	homeNotification: service(),
	router: service(),
	session: service(),
	topicSubscribedData: service(),
	isApp: false,
	instanceId: '',
	deviceToken: '',
	badge: '',

	init() {
		this._super(...arguments);

		// cek terlebih dahulu apakah ini cordova atau bukan
		if(window.cordova) {
			this.set('isApp', true);
		}
	},

	currentRouteName : computed('router.currentRouteName', {
		get() {
			let currentRoute = this.get('router').get('currentRouteName');
			let currentRouteArr = currentRoute.split(".");
			currentRoute = currentRouteArr[0];
			return currentRoute;
		}
	}),

	initFcmDaemon() {
		if(this.get('isApp') == false) return null;

		let _this = this;

		// register foreground push notification handler
		window.cordova.plugins.firebase.messaging.onMessage(function(payload){
			_this._pushNotificationReceived(true, payload);
		});

		// register background push notification handler
		window.cordova.plugins.firebase.messaging.onBackgroundMessage(function(payload){
			_this._pushNotificationReceived(false, payload);
		});

		// set permission agar push notification tetap muncul, meskipun aplikasi sedang aktif
		window.cordova.plugins.firebase.messaging.requestPermission({forceShow: true});

		// set instance id
		window.cordova.plugins.firebase.messaging.getInstanceId().then(function(instanceId) {
			_this.set('instanceId', instanceId);
		});

		// set device token
		window.cordova.plugins.firebase.messaging.getToken().then(function(token) {
			_this.set('deviceToken', token);
		});

		// handler ketika device token ter-update
		window.cordova.plugins.firebase.messaging.onTokenRefresh(function() {
			_this._deviceTokenUpdated();
		});

		// check if channel exists, if not, create one
		window.cordova.plugins.firebase.messaging.findChannel('news').then(function(channel) {
			if (channel == null) {
				_this.createChannel('hearts_news', 'News Notification');
			}
		}).catch(function(e){
			console.log(e);
		});

		window.cordova.plugins.firebase.messaging.findChannel('news').then(function(channel) {
			if (channel == null) {
				_this.createChannel('hearts_inbox', 'Inbox Notification');
			}
		}).catch(function(e){
			console.log(e);
		});
	},

	// method untuk mengambil device token
	getToken() {
		if(this.get('isApp') == false) return null;

		let _this = this;
		return window.cordova.plugins.firebase.messaging.getToken().then(function(token) {
			_this.set('deviceToken', token);
			return token;
		});
	},

	// method untuk mengambil instance id
	getInstanceId() {
		if(this.get('isApp') == false) return null;

		let _this = this;
		return window.cordova.plugins.firebase.messaging.getInstanceId().then(function(instanceId) {
			_this.set('instanceId', instanceId);
			return instanceId;
		});
	},

	// method untuk subscribe ke topik
	subscribeToTopic(topicName) {
		if(this.get('isApp') == false) return null;

		return window.cordova.plugins.firebase.messaging.subscribe(topicName);
	},

	// method untuk unsubscribe dari topik
	unsubscribeFromTopic(topicName) {
		if(this.get('isApp') == false) return null;

		return window.cordova.plugins.firebase.messaging.unsubscribe(topicName);
	},

	// method untuk mengambil nilai dari badge
	getBadge() {
		if(this.get('isApp') == false) return null;

		let _this = this;
		return window.cordova.plugins.firebase.messaging.getBadge().then(function(value) {
			_this.set('badge', value);
			return value;
		});
	},

	createChannel(channel_id, channel_name, channel_importance = 4) {
		if(this.get('isApp') == false) return null;

		window.cordova.plugins.firebase.messaging.createChannel({
			id: channel_id,
			name: channel_name,
			importance: channel_importance
		});
	},

	findChannel(channelId) {
		if(this.get('isApp') == false) return null;

		return cordova.plugins.firebase.messaging.findChannel(channelId).then(function(channel) {
			return channel;
		});
	},

	listChannels() {
		if(this.get('isApp') == false) return null;

		return cordova.plugins.firebase.messaging.listChannels().then(function(channels) {
			return channels;
		});
	},

	deleteChannel(channelId) {
		if(this.get('isApp') == false) return null;

		cordova.plugins.firebase.messaging.deleteChannel(channelId);
	},

	// handler ketika notification diterima
	_pushNotificationReceived(isForegroud, payload) {
		if(this.get('isApp') == false) return null;

		let msg = 'foreground';
		if(!isForegroud) msg = 'background';
		console.log('new ' + msg + ' FCM message: ', payload);
		
		let notificationType = 'unknown';
		if(payload.notificationType != null) {
			notificationType = payload.notificationType;
		}

		switch(notificationType) {
			case 'inbox':
				let dataSource = payload.dataSource;
				let documentType = payload.documentType;

				if(isForegroud) {
					if(this.currentRouteName == 'home') {
						this.homeNotification.refreshHomeNotification();
					}
				} else {
					if(documentType == undefined || documentType == null || documentType == '') {
						this.transitionToRoute('inbox.all'); 
					} else {
						if(dataSource == 'DMS') {
							this.transitionToRoute('inbox.inbox-approval-dms', documentType); 
						} else if(dataSource == 'HOYU') {
							this.transitionToRoute('inbox.inbox-approval-hoyu', documentType); 
						} else {
							this.transitionToRoute('inbox.all'); 
						}
					}
				}
				
				// TODO: untuk offline mode, download data disini
				break;

			case 'news':
				if(!isForegroud) {
					// TODO: bawa ke halaman news
				}

				// TODO: untuk offline mode, download data disini
				break;

			case 'unknown':
				break;
		}
	},

	// jika terjadi token update, daftarkan kembali token
	_deviceTokenUpdated() {
		if(this.get('isApp') == false) return null;

		let _this = this;
		return window.cordova.plugins.firebase.messaging.getToken().then(function(token) {
			// update reference ke token
			_this.set('deviceToken', token);

			// submit ke backend
			_this.registerToken(_this.sessionAccount.currentUser);
			return token;
		});
	},

	// register device token & user yang login
	registerToken(user) {
		if(this.get('isApp') == false) return null;

		// subscribe ke topic yang sesuai dengan role management
		let topic_name = 'NEWS_' + user.roleManagementId;
		this.set('session.data.topic', topic_name);
		this.subscribeToTopic(topic_name);
		console.log('subscribed to: ' + topic_name);

		// save token to back end
		let newToken = this.fcmTokenData.createRecord({
			coreUser: user,
			coreUserId: user.id,
			fcmToken: this.deviceToken
		});
		this.fcmTokenData.save(newToken).then(function(result){
		}).catch(function(e) {
		});
	},

	// unsubscribe dari topic yang di subscribe ketika login
	logout() {
		if(this.get('isApp') == false) return null;

		let topic_name = this.get('session.data.topic');
		this.unsubscribeFromTopic(topic_name);
		console.log('unsubscribed from: ' + topic_name);
	},

	// untuk pindah halaman
	transitionToRoute(route, params = null) {
		this.get('router').transitionTo(route, params);
	},
});