Skip to content

Instantly share code, notes, and snippets.

@huogerac
Created June 7, 2018 03:34
Show Gist options
  • Save huogerac/448885edb6d3c0690b2ae57bcde2a499 to your computer and use it in GitHub Desktop.
Save huogerac/448885edb6d3c0690b2ae57bcde2a499 to your computer and use it in GitHub Desktop.
Push Notifications
/* eslint-disable */
export default {
user_profile: _mockasync(user_profile),
update_token: _mockasync(update_token)
}
/**
* Get the user profile from the backend
* @param ask_for_permission: it IS NOT a good idea ask for ALLOW push notifications in the first time the user gets in the website.
* perhaps after he browsers or watch the first video.
* @param token: after the user gives permission (ALLOW), the firebase send a token which will be used to send message for the user device.
*/
function user_profile(user_id) {
return {
user_id: user_id,
push_notification: {
ask_for_permission: true,
token: null
}
}
}
/**
* If the user clear data or change the computer etc..he will receive a new token from the firebase messaging.
* So we need to keep the backend updated
* @param token: new token
*/
function update_token(user_profile, token) {
user_profile.push_notification.token = token
return user_profile
}
function _mockasync(f){
function mocked(){
var res = f.apply(this, arguments)
return new Promise(function(resolve, reject){
setTimeout(function(){
resolve({data: res})
}, 600);
})
}
return mocked
}
// /static/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js')
var config = {
apiKey: 'AIzaSyABRALdPhSmLH_NdwxQ27gcwG-_v9QacV4',
authDomain: 'evolutiodev.firebaseapp.com',
databaseURL: 'https://evolutiodev.firebaseio.com/',
projectId: 'evolutiodev',
storageBucket: 'evolutiodev.appspot.com',
messagingSenderId: '646469414520'
}
firebase.initializeApp(config)
const messaging = firebase.messaging()
import firebase from 'firebase'
var config = {
apiKey: 'AIzaSyABRALdPhSmLH_NdwxQ27gcwG-_v9QacV4',
authDomain: 'evolutiodev.firebaseapp.com',
databaseURL: 'https://evolutiodev.firebaseio.com/',
projectId: 'evolutiodev',
storageBucket: 'evolutiodev.appspot.com',
messagingSenderId: '646469414520'
}
firebase.initializeApp(config)
export default {
messaging: firebase.messaging()
}
<template>
<div>
<!-- componente que encapsula o PUSH NOTIFICATION -->
<push-notification
ref="pushNotification"
:currentToken="userToken"
@update-token="onUpdateToken"
@new-message="onNewMessage" />
<!-- snackbar que mostra as notifications -->
<div id="snackbar-message" class="mdl-js-snackbar mdl-snackbar">
<div class="mdl-snackbar__text"></div>
<button class="mdl-snackbar__action" type="button"></button>
</div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--3-col mdl-cell mdl-cell--1-col-tablet mdl-cell--hide-phone"></div>
<div class="mdl-cell mdl-cell--6-col mdl-cell--4-col-phone">
<!-- mostra uma mensagem amigável para que o visitante que faça o usuário ter vontade de habilitar as
notificaçes -->
<div v-show="askForPermission && !userToken" class="headline" style="background-color: #ff897d; padding: 20px; border-radius: 6px; color: #fff;">
Hey, click here to start receiving our amazing push notifications!!!
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect"
@click="enableNotifications">
Enable notifications
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import PushNotification from '@/components/PushNotification'
import api from '@/api/api'
export default {
components: {
PushNotification
},
methods: {
enableNotifications () {
this.$refs.pushNotification.askForPermission()
},
onUpdateToken (newToken) {
this.userToken = newToken
// send token to the server
api.update_token(this.userProfile, this.userToken)
},
onNewMessage (message) {
var snackbarContainer = document.querySelector('#snackbar-message')
var data = {
message: message.notification.title + ': ' + message.notification.body,
timeout: 10000,
actionText: 'OK'
}
snackbarContainer.MaterialSnackbar.showSnackbar(data)
}
},
created () {
var userLoggedId = 1
// check if user has a token
api.user_profile(userLoggedId).then((response) => {
this.userProfile = response.data
this.userToken = this.userProfile.push_notification.ask_for_permission.token
if (this.userProfile.push_notification.ask_for_permission) {
setTimeout(() => {
// Simulate it wont ask for permission in the first user access
this.askForPermission = true
}, 4000)
}
})
},
data () {
return {
userProfile: {},
askForPermission: false,
userToken: null
}
}
}
</script>
<style scoped>
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Push Notifications</title>
<!-- ADD THIS -->
<link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>static/manifest.json">
...
</head>
<body>
... the latest VueJs Template already has this service worker
<%= htmlWebpackPlugin.options.serviceWorkerLoader %>
</body>
</html>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueResource from 'vue-resource'
import VueFire from 'vuefire'
Vue.config.productionTip = false
Vue.use(VueResource)
Vue.use(VueFire)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
template: '<App/>',
components: { App }
})
{
"name": "cropchat",
"short_name": "cropchat",
"gcm_sender_id": "103953800507",
"icons": [
{
"src": "/static/img/icons/cropchat-icon-64x64.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/static/img/icons/cropchat-icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "/static/img/icons/cropchat-icon-256x256.png",
"sizes": "256x256",
"type": "image/png"
},
{
"src": "/static/img/icons/cropchat-icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "fullscreen",
"orientation": "portrait",
"background_color": "#2196f3",
"theme_color": "#2196f3"
}
{
"name": "pushnotification",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "Roger Camargo <huogerac@gmail.com>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
"test": "npm run unit",
"lint": "eslint --ext .js,.vue src test/unit/specs"
},
"dependencies": {
"firebase": "^5.0.4",
"material-design-lite": "^1.3.0",
"vue": "^2.5.2",
"vue-resource": "^1.5.1",
"vue-router": "^3.0.1",
"vuefire": "^1.4.5",
"xml-parser": "^1.2.1"
},
"devDependencies": {
"ngrok": "^3.0.1",
"autoprefixer": "^7.1.5",
"babel-core": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-loader": "^7.1.2",
"babel-plugin-istanbul": "^4.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.6.0",
"babel-preset-stage-2": "^6.24.1",
"babel-register": "^6.26.0",
"chai": "^4.1.2",
"chalk": "^2.1.0",
"connect-history-api-fallback": "^1.4.0",
"copy-webpack-plugin": "^4.1.1",
"cross-env": "^5.0.5",
"css-loader": "^0.28.7",
"cssnano": "^3.10.0",
"eslint": "^4.9.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-html": "^3.2.2",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.16.2",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.5",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"http-proxy-middleware": "^0.17.4",
"inject-loader": "^3.0.1",
"karma": "^1.7.1",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.4",
"karma-phantomjs-shim": "^1.5.0",
"karma-sinon-chai": "^1.3.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.5",
"mocha": "^4.0.1",
"opn": "^5.1.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.3.0",
"phantomjs-prebuilt": "^2.1.15",
"rimraf": "^2.6.2",
"semver": "^5.4.1",
"shelljs": "^0.7.8",
"sinon": "^4.0.1",
"sinon-chai": "^2.14.0",
"sw-precache-webpack-plugin": "^0.11.5",
"uglify-es": "^3.1.3",
"url-loader": "^0.6.2",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.3",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.7.1",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.19.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
<template>
</template>
<script>
import firebase from '../service/firebase'
export default {
props: ['currentToken'],
data () {
return {
hasServiceWorker: false
}
},
mounted () {
this.initialize()
},
methods: {
initialize () {
if (!('serviceWorker' in navigator)) {
console.warn('serviceWorker not working')
return
}
if (!('PushManager' in window)) {
console.warn('PushManager not working')
return
}
this.hasServiceWorker = true
},
askForPermission () {
if (!this.hasServiceWorker) {
return
}
// console.firebase | project settins | cloud message | web config | Key pair
firebase.messaging.usePublicVapidKey('BK8JSwxoV2WXvivBQ0deKPy9PVTRaYcYmuwGjJWGpgTAZ7-NM48H1ScVsO6EvMhP7O9jhSGp39XFtRQCPgfDAJI')
navigator.serviceWorker.register('./static/firebase-messaging-sw.js')
.then((registration) => {
firebase.messaging.useServiceWorker(registration)
firebase.messaging.requestPermission().then(() => {
firebase.messaging.getToken().then((token) => {
if (token !== this.currentToken) {
this.$emit('update-token', token)
}
}).catch((err) => console.log('--- token error:', err))
}).catch(function (err) {
console.log('Unable to get permission to notify.', err)
})
}).catch(err => {
console.log('error register', err)
})
firebase.messaging.onMessage((payload) => {
this.$emit('new-message', payload)
})
}
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment