Last active
November 23, 2023 12:05
-
-
Save echr/a1195e083e6ff4f980698fa06ebfefc3 to your computer and use it in GitHub Desktop.
Simple Laravel + Vue + Laravel Mix + Firebase Notification (PWA, Offline)
This file contains hidden or 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
// FILE PATH: /resources/js/app.js | |
require('./bootstrap'); | |
// Import Service Worker Registry | |
require('./extensions/sw-registry'); | |
import Vue from 'vue'; | |
... |
This file contains hidden or 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
// FILE PATH: /resources/js/firebase.js | |
import * as firebase from 'firebase/app'; | |
require('firebase/messaging'); | |
// Change with your own Sender ID | |
const initializedFirebaseApp = firebase.initializeApp({ | |
messagingSenderId: '#####' | |
}); | |
let messaging = null; | |
if (firebase.messaging.isSupported()) { | |
messaging = initializedFirebaseApp.messaging(); | |
// Change with your own VapidKey | |
messaging.usePublicVapidKey( | |
'#####' | |
); | |
messaging.onMessage((payload) => { | |
const notificationTitle = payload.notification.title; | |
const notificationOptions = { | |
body: payload.notification.body, | |
icon: '/android-chrome-144x144.png', | |
}; // Your notification icon in /public directory | |
if (!('Notification' in window)) { | |
console.log('This browser does not support system notifications'); | |
} else if (Notification.permission === 'granted') { | |
let notification = new Notification(notificationTitle,notificationOptions); | |
notification.onclick = function(event) { | |
event.preventDefault(); | |
window.open(payload.notification.click_action , '_blank'); | |
notification.close(); | |
}; | |
} | |
}); | |
} | |
export { messaging }; |
This file contains hidden or 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
// FILE PATH: /resources/js/service-worker.js | |
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js'); | |
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-app.js'); | |
importScripts('https://www.gstatic.com/firebasejs/6.3.4/firebase-messaging.js'); | |
// Change with your own Sender ID | |
firebase.initializeApp({ | |
'messagingSenderId': '######' | |
}); | |
const messaging = firebase.messaging(); | |
messaging.setBackgroundMessageHandler(function(payload) { | |
const notification = JSON.parse(payload.data.data); | |
const notificationTitle = notification.title; | |
const notificationOptions = { | |
body: notification.body, | |
icon: '/android-chrome-144x144.png', | |
}; | |
return self.registration.showNotification(notificationTitle, | |
notificationOptions); | |
}); | |
if (workbox) { | |
// injected assets by Workbox CLI | |
workbox.precaching.precacheAndRoute([]); | |
// js/css files | |
workbox.routing.registerRoute( | |
/\.(?:js|css)$/, | |
new workbox.strategies.StaleWhileRevalidate({ | |
cacheName: 'static-resources', | |
}) | |
); | |
// // images | |
workbox.routing.registerRoute( | |
// Cache image files. | |
/\.(?:png|jpg|jpeg|svg|gif)$/, | |
// Use the cache if it's available. | |
new workbox.strategies.CacheFirst({ | |
// Use a custom cache name. | |
cacheName: 'image-cache', | |
plugins: [ | |
new workbox.expiration.Plugin({ | |
// Cache upto 50 images. | |
maxEntries: 50, | |
// Cache for a maximum of a week. | |
maxAgeSeconds: 7 * 24 * 60 * 60, | |
}), | |
new workbox.cacheableResponse.Plugin({ | |
statuses: [200] | |
}) | |
], | |
}) | |
); | |
const networkFirstHandler = new workbox.strategies.NetworkFirst({ | |
cacheName: 'dynamic', | |
plugins: [ | |
new workbox.expiration.Plugin({ | |
maxEntries: 10 | |
}), | |
new workbox.cacheableResponse.Plugin({ | |
statuses: [200] | |
}) | |
] | |
}); | |
const FALLBACK_URL = workbox.precaching.getCacheKeyForURL('/offline.html'); // Your offline page, placed in /public dir, and will be cached | |
const matcher = ({ event }) => event.request.mode === 'navigate'; | |
const handler = args => | |
networkFirstHandler | |
.handle(args) | |
.then(response => response || caches.match(FALLBACK_URL)) | |
.catch(() => caches.match(FALLBACK_URL)); | |
workbox.routing.registerRoute(matcher, handler); | |
self.addEventListener('message', function (event) { | |
console.log('user request for update... (' + event.data.action + ')'); | |
if (event.data.action === 'skipWaiting') { | |
self.skipWaiting(); | |
} | |
}); | |
} |
This file contains hidden or 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
// FILE PATH: /resources/js/sw-registry.js | |
// (optional) If you using firebase notification | |
import { messaging } from 'firebase'; | |
let newWorker; | |
// Notify user if service worker file has changed.. and need to update | |
// in your layout blade file create this snippet for notification for example | |
// | |
// <div id="sw-snackbar">A new version of this app is available. Click <a id="reload">here</a> to update.</div> | |
// | |
function showUpdateBar() { | |
let snackbar = document.getElementById('sw-snackbar'); | |
snackbar.className = 'show'; | |
} | |
document.getElementById('reload').addEventListener('click', function(){ | |
newWorker.postMessage({ action: 'skipWaiting' }); | |
}); | |
if ('serviceWorker' in navigator) { | |
window.addEventListener('load', () => { | |
navigator.serviceWorker.register('/offline.js').then(reg => { | |
reg.addEventListener('updatefound', () => { | |
newWorker = reg.installing; | |
newWorker.addEventListener('statechange', () => { | |
switch (newWorker.state) { | |
case 'installed': | |
if (navigator.serviceWorker.controller) { | |
// Show update bar | |
showUpdateBar(); | |
} | |
break; | |
} | |
}); | |
}); | |
}).catch((err) => { | |
console.log('ServiceWorker registration failed: ', err); | |
}); | |
let refreshing; | |
navigator.serviceWorker.addEventListener('controllerchange', function () { | |
if (refreshing) return; | |
window.location.reload(); | |
refreshing = true; | |
}); | |
}); | |
} |
This file contains hidden or 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
const mix = require('laravel-mix'); | |
const WebpackShellPlugin = require('webpack-shell-plugin'); | |
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer') | |
.BundleAnalyzerPlugin; | |
mix.setPublicPath('public'); | |
mix.sass('./resources/sass/app.scss', '/css/app.css'); | |
mix.js('./resources/js/app.js', '/js/webapp.js') | |
.extract(['axios', 'vue', 'accounting', 'vuex', 'vuex-router-sync', 'vue-router', 'vue-lazyload', 'vue-i18n', 'vue-events', 'vee-validate']) | |
.webpackConfig({ | |
output: { | |
chunkFilename: 'js/chunks/[name].js' | |
} | |
}); | |
if (mix.inProduction()) { | |
mix.webpackConfig({ | |
plugins: [new BundleAnalyzerPlugin()] | |
}); | |
mix.version(); | |
mix.disableNotifications(); | |
} | |
/** | |
* Publishing the assets | |
*/ | |
mix.webpackConfig({ | |
plugins: [ | |
new WebpackShellPlugin({ | |
onBuildEnd: [ | |
'npx workbox injectManifest workbox-config.js' | |
] | |
}) | |
] | |
}); |
This file contains hidden or 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
module.exports = { | |
// Path to be offline cache | |
'globDirectory': 'public/', | |
'globPatterns': [ | |
'/**/*.{css,ico,ttf,woff,svg,png,jpg,php,js,xml,webmanifest,json,txt,gif,md,html,scss,eot,woff2,swf,otf}', | |
'offline.html', | |
'mix-manifest.json', | |
], | |
'swDest': 'public/offline.js', | |
'globIgnores': [], | |
'swSrc': 'resources/js/service-worker.js' | |
}; |
halo gan ada tutorial gk ? cara untuk membuat notifikasi reminder menggunakan vue.js + laravel
Nice , do you have any projects with laravel ,vue and firebase ?
Nice , do you have any projects with laravel ,vue and firebase ?
how would you look in firebase ???
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bisa diperjelas "aktifkan" seperti apa ya yg dimaksud?,
service-worker.js
dansw-registry.js
ketika diload diapp.js
akan otomatis mengaktifkan service worker dan bisa digunakan untuk fitur-fitur PWA (offline, notification, dll). Jika tidak ingin menggunakan firebase notification cukup di hapus aja script import firebase-nya.