I am building a web app using firebase local emulation. I have firebase authentication working but I’m getting errors that don’t make sense when trying to query my database.
Here is the relevant testing code:
import { initializeApp, getApps } from 'firebase/app';
import { getAuth, connectAuthEmulator, signInWithEmailAndPassword, signOut } from 'firebase/auth';
import { executeQuery, getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect';
import { getStudentByemail, connectorConfig } from '@firebasegen/default-connector';
let fbApp = null;
let dConnect = null;
let fbInitialized = false;
async function fetchFbConfig() {
try {
const response = await fetch('http://localhost:5001/<project-name>/us-central1/getApiKey');
if (!response.ok) {
throw new Error('Network response was not ok');
}
const fbConfig = await response.json();
return fbConfig;
} catch (error) {
console.error('Error fetching Firebase config:', error);
}
}
// Initialize Firebase with the fetched config
fetchFbConfig()
.then(fbConfig => {
if (!fbConfig) throw new Error('Failed to fetch Firebase config');
// Initialize Firebase only if it hasn't been initialized already
if (!getApps().length) {
fbApp = initializeApp(fbConfig);
const auth = getAuth(fbApp);
connectAuthEmulator(auth, "http://127.0.0.1:9099");
console.log('Initializing DataConnect...');
dConnect = getDataConnect(connectorConfig);
if (!dConnect) throw new Error('dataConnect not initialized');
connectDataConnectEmulator(dConnect, 'localhost', 9399);
dConnect.setInitialized();
fbInitialized = true;
window.GetStudentByemail = async function(_email) {
if (!fbInitialized || !dConnect) {
throw new Error('Firebase/DataConnect not initialized');
}
console.log('GetStudentByemail function activated with ', _email);
try {
const query = getStudentByemail({ email: _email });
console.log('Query:', query);
const qryRef = await executeQuery(dConnect, query);
return new Promise((resolve, reject) => {
qryRef.onSnapshot(
snapshot => resolve(snapshot.data()),
error => reject(error)
);
});
} catch (error) {
console.error('GetStudentByemail error:', error);
throw error;
}
};
window.signInUser = function(email, password, callback) {
if (!fbInitialized) {
console.error('Firebase not initialized');
callback(false);
return;
}
signInWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
if (userCredential.user.emailVerified) {
console.log('User signed in:', userCredential.user);
callback(true);
} else {
console.error('Email not verified.');
signOut(auth);
callback(false);
}
})
.catch((error) => {
console.error('Error signing in:', error.code, error.message);
callback(false);
});
};
window.signInUser("<email>", "<password>", async function(isLoggedIn) {
if (isLoggedIn) {
try {
console.log('fetchStudentData function activated with ', "<email>");
const studentData = await window.GetStudentByemail("<email>");
console.log('Fetched student data:', studentData);
} catch (error) {
console.error('Error fetching student data:', error);
}
} else {
console.log('User not logged in.');
}
});
}
})
.catch((error) => {
console.error('Error initializing Firebase:', error);
});
The console log is:
Initializing DataConnect... index.js:35:18
User signed in: Object <> index.js:76:26
fetchStudentData function activated with <email> index.js:93:26
GetStudentByemail function activated with <email> index.js:48:20
GetStudentByemail error: FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call initializeApp() first (app/no-app).
The error is being thrown on the line
const query = getStudentByemail({ email: _email });
in the function GetStudentByemail. The query getStudentByemail give the correct response when called from within the data connection execution terminal in VSCode and is present and correct in the SDK.
Obviously the firebase app is created because the user is signed in and dataConnect is also correctly initialised, so the only thing that makes sense is if the execution of the promise preceeds the initialisation of the firebase app. I’ve read about promises being executed from a different queue (microtasks) that maybe causing this error, but I’m lost and clutching at straws and even if this is the case I have no idea how to solve.
Please excuse any incorrect terminology, I’m not a programmer so I’m very much out of my depth here.
Any help would be greatly appreciated.
2
Answers
I have managed to remove this error, I was passing the dataConnect instance to the wrong function, I should have been passing it to get getStudentByemailRef not executeQuery. There were other errors in my original code, the following code clears the No Firebase App Query and correctly queries my database, it may help anyone else who is working with Data Connect local emulation.
Thanks Doug for your help.
I haven’t used Data Connect before, but it seems to me that you should import
getStudentByemailRef
instead ofgetStudentByemail
. The "ref" version is executed usingexecuteQuery
, while the "non-ref" version ("action shortcut functions") according to the docs is just a function you call directly to execute the query. Or maybe you just want to skipexecuteQuery
and just invoke the action shortcut query directly instead of the ref. I’m making this guess based on what I see in the documentation. I suggest patterning your code based on what you see there.