added unsubscribe
This commit is contained in:
138
app.js
138
app.js
@@ -42,38 +42,144 @@ const cameraCancelButton = document.getElementById('cameraCancelButton');
|
||||
let stream = null;
|
||||
|
||||
async function subscribeToPushNotifications() {
|
||||
if ('serviceWorker' in navigator && 'PushManager' in window) {
|
||||
try {
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(PUBLIC_VAPID_KEY)
|
||||
});
|
||||
let buttonId = BUTTON_ID;
|
||||
// 1. Validate input buttonId
|
||||
if (!buttonId || typeof buttonId !== 'string' || buttonId.trim() === '') {
|
||||
console.error('Button ID is required to subscribe.');
|
||||
alert('Please provide a valid Flic Button ID/Serial.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Send subscription to your server
|
||||
await fetch(`${BACKEND_URL}/subscribe`, {
|
||||
// 2. Check for browser support
|
||||
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
|
||||
console.error('Push Messaging is not supported');
|
||||
alert('Sorry, Push Notifications are not supported by your browser.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 3. Request notification permission (requires user interaction)
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== 'granted') {
|
||||
console.error('Notification permission not granted.');
|
||||
alert('You denied notification permission. Please enable it in browser settings if you want to link the button.');
|
||||
return;
|
||||
}
|
||||
console.log('Notification permission granted.');
|
||||
|
||||
// 4. Get Service Worker registration
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
console.log('Service Worker is ready.');
|
||||
|
||||
// 5. Get existing subscription
|
||||
let existingSubscription = await registration.pushManager.getSubscription();
|
||||
let needsResubscribe = false;
|
||||
|
||||
if (existingSubscription) {
|
||||
console.log('Existing subscription found.');
|
||||
|
||||
// 6. Compare applicationServerKeys
|
||||
const existingKeyArrayBuffer = existingSubscription.options.applicationServerKey;
|
||||
if (!existingKeyArrayBuffer) {
|
||||
console.warn("Existing subscription doesn't have an applicationServerKey.");
|
||||
needsResubscribe = true; // Treat as needing resubscription
|
||||
} else {
|
||||
const existingKeyBase64 = arrayBufferToBase64(existingKeyArrayBuffer);
|
||||
console.log('Existing VAPID Key (Base64):', existingKeyBase64);
|
||||
console.log('Current VAPID Key (Base64): ', PUBLIC_VAPID_KEY);
|
||||
|
||||
if (existingKeyBase64 !== PUBLIC_VAPID_KEY) {
|
||||
console.log('VAPID keys DO NOT match. Unsubscribing the old one.');
|
||||
await existingSubscription.unsubscribe();
|
||||
console.log('Successfully unsubscribed old subscription.');
|
||||
existingSubscription = null; // Clear it so we subscribe anew below
|
||||
needsResubscribe = true; // Explicitly flag for clarity
|
||||
} else {
|
||||
console.log('VAPID keys match. No need to resubscribe.');
|
||||
needsResubscribe = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('No existing subscription found.');
|
||||
needsResubscribe = true; // No subscription exists, so we need one
|
||||
}
|
||||
|
||||
// 7. Subscribe if needed (no existing sub or keys mismatched)
|
||||
let finalSubscription = existingSubscription; // Use existing if keys matched
|
||||
if (needsResubscribe || !finalSubscription) {
|
||||
console.log('Attempting to subscribe with current VAPID key...');
|
||||
const applicationServerKey = urlBase64ToUint8Array(PUBLIC_VAPID_KEY);
|
||||
finalSubscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: applicationServerKey
|
||||
});
|
||||
console.log('New push subscription obtained:', finalSubscription);
|
||||
}
|
||||
|
||||
// 8. Send the final subscription (new or validated existing) to your server
|
||||
if (!finalSubscription) {
|
||||
console.error("Failed to obtain a final subscription object.");
|
||||
alert("Could not get subscription details. Please try again.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Sending subscription for button "${buttonId}" to backend...`);
|
||||
const response = await fetch(`${BACKEND_URL}/subscribe`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
button_id: BACKEND_URL,
|
||||
subscription: subscription // The PushSubscription object
|
||||
button_id: buttonId,
|
||||
subscription: finalSubscription
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
pushSubscription = subscription;
|
||||
console.log('Push subscription successful');
|
||||
// 9. Handle the server response
|
||||
if (response.ok) {
|
||||
const result = await response.json();
|
||||
console.log('Push subscription successfully sent to server:', result.message);
|
||||
} else {
|
||||
let errorMessage = `Server error: ${response.status}`;
|
||||
try {
|
||||
const errorResult = await response.json();
|
||||
errorMessage = errorResult.message || errorMessage;
|
||||
} catch (e) {
|
||||
errorMessage = response.statusText || errorMessage;
|
||||
}
|
||||
console.error('Failed to send push subscription to server:', errorMessage);
|
||||
alert(`Failed to save notification settings on server: ${errorMessage}`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error subscribing to push:', error);
|
||||
console.error('Error during push subscription process:', error);
|
||||
// Handle potential errors from permission request, SW registration, get/unsubscribe/subscribe, or fetch network issues
|
||||
if (error.name === 'InvalidStateError') {
|
||||
alert(`Subscription failed: ${error.message}. Please try again or ensure no conflicting subscriptions exist.`);
|
||||
} else {
|
||||
alert(`An error occurred: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to convert ArrayBuffer to Base64 string (URL safe)
|
||||
function arrayBufferToBase64(buffer) {
|
||||
let binary = '';
|
||||
const bytes = new Uint8Array(buffer);
|
||||
const len = bytes.byteLength;
|
||||
for (let i = 0; i < len; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return window.btoa(binary)
|
||||
.replace(/\+/g, '-')
|
||||
.replace(/\//g, '_')
|
||||
.replace(/=+$/, ''); // Remove padding
|
||||
}
|
||||
|
||||
function urlBase64ToUint8Array(base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/-/g, '+')
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
|
||||
Reference in New Issue
Block a user