301 lines
15 KiB
JavaScript
301 lines
15 KiB
JavaScript
// Firebase Debugging Helper
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// Create a debugging panel
|
||
const debugPanel = document.createElement('div');
|
||
debugPanel.id = 'firebase-debug-panel';
|
||
debugPanel.style.position = 'fixed';
|
||
debugPanel.style.bottom = '20px';
|
||
debugPanel.style.right = '20px';
|
||
debugPanel.style.width = '400px';
|
||
debugPanel.style.maxHeight = '80vh';
|
||
debugPanel.style.overflowY = 'auto';
|
||
debugPanel.style.backgroundColor = '#f8f9fa';
|
||
debugPanel.style.border = '1px solid #dee2e6';
|
||
debugPanel.style.borderRadius = '4px';
|
||
debugPanel.style.padding = '15px';
|
||
debugPanel.style.boxShadow = '0 0.5rem 1rem rgba(0, 0, 0, 0.15)';
|
||
debugPanel.style.zIndex = '9999';
|
||
debugPanel.style.display = 'none';
|
||
|
||
debugPanel.innerHTML = `
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||
<h3 style="margin: 0; font-size: 16px;">Firebase Debug Console</h3>
|
||
<button id="close-debug-panel" style="background: none; border: none; cursor: pointer; font-size: 16px;">×</button>
|
||
</div>
|
||
<div id="firebase-config-status"></div>
|
||
<div id="firebase-connection-status"></div>
|
||
<div id="firebase-error-log" style="margin-top: 10px;"></div>
|
||
<div style="margin-top: 15px;">
|
||
<button id="test-firebase-connection" style="background-color: #007bff; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer;">Test Connection</button>
|
||
<button id="clear-error-log" style="background-color: #6c757d; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; margin-left: 5px;">Clear Log</button>
|
||
</div>
|
||
`;
|
||
|
||
document.body.appendChild(debugPanel);
|
||
|
||
// Add toggle button
|
||
const toggleButton = document.createElement('button');
|
||
toggleButton.id = 'toggle-debug-panel';
|
||
toggleButton.textContent = '🔍 Debug Firebase';
|
||
toggleButton.style.position = 'fixed';
|
||
toggleButton.style.bottom = '20px';
|
||
toggleButton.style.right = '20px';
|
||
toggleButton.style.backgroundColor = '#007bff';
|
||
toggleButton.style.color = 'white';
|
||
toggleButton.style.border = 'none';
|
||
toggleButton.style.borderRadius = '4px';
|
||
toggleButton.style.padding = '8px 15px';
|
||
toggleButton.style.cursor = 'pointer';
|
||
toggleButton.style.zIndex = '9998';
|
||
|
||
document.body.appendChild(toggleButton);
|
||
|
||
// Event listeners
|
||
document.getElementById('toggle-debug-panel').addEventListener('click', function() {
|
||
const panel = document.getElementById('firebase-debug-panel');
|
||
if (panel.style.display === 'none') {
|
||
panel.style.display = 'block';
|
||
this.style.display = 'none';
|
||
checkFirebaseConfig();
|
||
testFirebaseConnection();
|
||
}
|
||
});
|
||
|
||
document.getElementById('close-debug-panel').addEventListener('click', function() {
|
||
document.getElementById('firebase-debug-panel').style.display = 'none';
|
||
document.getElementById('toggle-debug-panel').style.display = 'block';
|
||
});
|
||
|
||
document.getElementById('test-firebase-connection').addEventListener('click', testFirebaseConnection);
|
||
|
||
document.getElementById('clear-error-log').addEventListener('click', function() {
|
||
document.getElementById('firebase-error-log').innerHTML = '';
|
||
});
|
||
|
||
// Check Firebase configuration
|
||
function checkFirebaseConfig() {
|
||
const configStatus = document.getElementById('firebase-config-status');
|
||
|
||
try {
|
||
if (typeof firebase === 'undefined') {
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error:</strong> Firebase is not defined. Make sure you've included the Firebase SDK.
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
// Check if firebaseConfig exists and has required fields
|
||
if (typeof firebaseConfig === 'undefined') {
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error:</strong> firebaseConfig is not defined.
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
const requiredFields = ['apiKey', 'authDomain', 'projectId'];
|
||
const missingFields = [];
|
||
|
||
for (const field of requiredFields) {
|
||
if (!firebaseConfig[field]) {
|
||
missingFields.push(field);
|
||
}
|
||
}
|
||
|
||
if (missingFields.length > 0) {
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error:</strong> Missing required fields in firebaseConfig: ${missingFields.join(', ')}
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
// Check if the API key looks like a placeholder
|
||
const apiKey = firebaseConfig.apiKey;
|
||
if (apiKey.includes('AIzaSyDQzGnxw9RUq0H5Qp-1Bv_qbCR_JRQJdvM') ||
|
||
apiKey.includes('your-api-key') ||
|
||
apiKey.includes('placeholder')) {
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #fff3cd; color: #856404; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Warning:</strong> Your API key appears to be a placeholder. Replace it with your actual Firebase API key.
|
||
</div>
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>How to fix:</strong>
|
||
<ol style="margin-top: 5px; padding-left: 20px;">
|
||
<li>Go to the <a href="https://console.firebase.google.com/" target="_blank">Firebase Console</a></li>
|
||
<li>Create a new project or select an existing one</li>
|
||
<li>Click the web icon (</>) to add a web app</li>
|
||
<li>Register your app with a nickname (e.g., "Fence Estimator")</li>
|
||
<li>Copy the firebaseConfig object</li>
|
||
<li>Replace the placeholder config in index.html with yours</li>
|
||
</ol>
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #d4edda; color: #155724; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Firebase Config:</strong> Looks valid
|
||
</div>
|
||
<div style="font-size: 12px; margin-bottom: 10px;">
|
||
<strong>API Key:</strong> ${firebaseConfig.apiKey}<br>
|
||
<strong>Project ID:</strong> ${firebaseConfig.projectId}<br>
|
||
<strong>Auth Domain:</strong> ${firebaseConfig.authDomain}
|
||
</div>
|
||
`;
|
||
|
||
} catch (error) {
|
||
configStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error checking config:</strong> ${error.message}
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
// Test Firebase connection
|
||
function testFirebaseConnection() {
|
||
const connectionStatus = document.getElementById('firebase-connection-status');
|
||
const errorLog = document.getElementById('firebase-error-log');
|
||
|
||
connectionStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #cce5ff; color: #004085; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Testing connection...</strong>
|
||
</div>
|
||
`;
|
||
|
||
try {
|
||
if (typeof firebase === 'undefined' || typeof firebase.firestore !== 'function') {
|
||
connectionStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error:</strong> Firebase Firestore is not available.
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
// Try to access Firestore
|
||
const db = firebase.firestore();
|
||
|
||
// Try to read from a test collection
|
||
db.collection('test').limit(1).get()
|
||
.then(() => {
|
||
connectionStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #d4edda; color: #155724; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Connection successful!</strong> Firebase is working correctly.
|
||
</div>
|
||
`;
|
||
})
|
||
.catch(error => {
|
||
let errorMessage = error.message;
|
||
let solution = '';
|
||
|
||
// Provide specific guidance based on error
|
||
if (error.code === 'permission-denied') {
|
||
solution = `
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-top: 10px;">
|
||
<strong>How to fix:</strong>
|
||
<ol style="margin-top: 5px; padding-left: 20px;">
|
||
<li>Go to the <a href="https://console.firebase.google.com/" target="_blank">Firebase Console</a></li>
|
||
<li>Select your project</li>
|
||
<li>Go to Firestore Database</li>
|
||
<li>Go to Rules tab</li>
|
||
<li>Update your rules to allow read/write access (for testing):</li>
|
||
<pre style="background-color: #f1f1f1; padding: 10px; border-radius: 4px; overflow-x: auto;">
|
||
rules_version = '2';
|
||
service cloud.firestore {
|
||
match /databases/{database}/documents {
|
||
match /{document=**} {
|
||
allow read, write: if true; // WARNING: Only for testing!
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
<li>Click "Publish"</li>
|
||
</ol>
|
||
</div>
|
||
`;
|
||
} else if (error.code === 'invalid-argument' || errorMessage.includes('400')) {
|
||
solution = `
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-top: 10px;">
|
||
<strong>How to fix:</strong>
|
||
<ol style="margin-top: 5px; padding-left: 20px;">
|
||
<li>The 400 error usually means your Firebase configuration is invalid</li>
|
||
<li>Make sure you've replaced the placeholder config with your own</li>
|
||
<li>Check that your project exists in the <a href="https://console.firebase.google.com/" target="_blank">Firebase Console</a></li>
|
||
<li>Verify that Firestore is enabled in your project</li>
|
||
</ol>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
connectionStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Connection failed:</strong> ${errorMessage}
|
||
<div style="margin-top: 5px;"><strong>Error code:</strong> ${error.code || 'unknown'}</div>
|
||
</div>
|
||
${solution}
|
||
`;
|
||
|
||
// Add to error log
|
||
const timestamp = new Date().toLocaleTimeString();
|
||
errorLog.innerHTML += `
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-bottom: 10px; font-size: 12px;">
|
||
<div><strong>${timestamp}</strong></div>
|
||
<div><strong>Error:</strong> ${errorMessage}</div>
|
||
<div><strong>Code:</strong> ${error.code || 'unknown'}</div>
|
||
</div>
|
||
`;
|
||
});
|
||
|
||
} catch (error) {
|
||
connectionStatus.innerHTML = `
|
||
<div style="padding: 10px; background-color: #f8d7da; color: #721c24; border-radius: 4px; margin-bottom: 10px;">
|
||
<strong>Error testing connection:</strong> ${error.message}
|
||
</div>
|
||
`;
|
||
|
||
// Add to error log
|
||
const timestamp = new Date().toLocaleTimeString();
|
||
errorLog.innerHTML += `
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-bottom: 10px; font-size: 12px;">
|
||
<div><strong>${timestamp}</strong></div>
|
||
<div><strong>Error:</strong> ${error.message}</div>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
// Monitor for Firebase errors
|
||
const originalConsoleError = console.error;
|
||
console.error = function() {
|
||
originalConsoleError.apply(console, arguments);
|
||
|
||
// Check if this is a Firebase error
|
||
const errorString = Array.from(arguments).join(' ');
|
||
if (errorString.includes('firebase') || errorString.includes('firestore') || errorString.includes('400')) {
|
||
const errorLog = document.getElementById('firebase-error-log');
|
||
const timestamp = new Date().toLocaleTimeString();
|
||
|
||
errorLog.innerHTML += `
|
||
<div style="padding: 10px; background-color: #f8f9fa; border-radius: 4px; margin-bottom: 10px; font-size: 12px;">
|
||
<div><strong>${timestamp}</strong></div>
|
||
<div><strong>Console Error:</strong> ${errorString}</div>
|
||
</div>
|
||
`;
|
||
|
||
// Show the debug button with an alert indicator
|
||
const toggleButton = document.getElementById('toggle-debug-panel');
|
||
if (toggleButton.style.display !== 'none') {
|
||
toggleButton.textContent = '🔴 Debug Firebase';
|
||
toggleButton.style.backgroundColor = '#dc3545';
|
||
}
|
||
}
|
||
};
|
||
});
|