Created
June 7, 2018 03:34
-
-
Save huogerac/448885edb6d3c0690b2ae57bcde2a499 to your computer and use it in GitHub Desktop.
Push Notifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// /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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 } | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "pushnotification", | |
"version": "1.0.0", | |
"description": "A Vue.js project", | |
"author": "Roger Camargo <[email protected]>", | |
"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" | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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