I currently have a project set up through VueCLI and firebase-tools and can't seem to be able to attach the Firebase Auth emulator to my project locally.
My Firebase Set-up file:
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';
const configOptions = {
apiKey: process.env.VUE_APP_FIREBASE_API_KEY,
authDomain: process.env.VUE_APP_FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.VUE_APP_FIREBASE_DB_URL,
projectId: process.env.VUE_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.VUE_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.VUE_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.VUE_APP_FIREBASE_APP_ID,
measurementId: process.env.VUE_APP_FIREBASE_MEASUREMENT_ID
};
firebase.initializeApp(configOptions);
if (process.env.NODE_ENV === "development"){
firebase.firestore().settings({ host: 'localhost:8080', ssl: false });
firebase.auth().useEmulator('http://localhost:9099/');
}
export const firebaseauth = firebase.auth();
export const firestore = firebase.firestore();
export const firebasestorage = firebase.storage();
export default firebase;
My .env.development file
VUE_APP_I18N_LOCALE=en
VUE_APP_I18N_FALLBACK_LOCALE=en
VUE_APP_FIREBASE_API_KEY="xx"
VUE_APP_FIREBASE_AUTH_DOMAIN="localhost:9099"
VUE_APP_FIREBASE_DB_URL="http://localhost:4000"
VUE_APP_FIREBASE_PROJECT_ID="xx"
VUE_APP_FIREBASE_STORAGE_BUCKET="xx"
VUE_APP_FIREBASE_MESSAGING_SENDER_ID="xx"
VUE_APP_FIREBASE_APP_ID="xx"
VUE_APP_FIREBASE_MEASUREMENT_ID="xx"
When navigating to localhost:5000 (emulated hosting), I get the error:
Uncaught TypeError: firebase_app__WEBPACK_IMPORTED_MODULE_0___default.a.auth(...).useEmulator is not a function
useEmulator comes directly from Google's Firebase Documentation so I'm unsure what I'm doing incorrectly.
It may be that you're still using a firebase version older than version 8.0.0, in that case the method you'd want to call is the .useFunctionsEmulator method (deprecated since v8.0.0):
firebase.functions().useFunctionsEmulator('http://localhost:5001');
If you are using the v8 SDK, however, here is how you can connect your app to the emulator:
firebase.auth().useEmulator("http://localhost:9099"); // Connect to the Authentication emulator
firebase.functions().useEmulator("localhost", 5001); // Connect to the Cloud Functions emulator
With the JS SDK v9, you'll need to use connectFirestoreEmulator function.
See docs https://firebase.google.com/docs/emulator-suite/connect_firestore
import { initializeApp } from "firebase/app";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
const config = {} //your config object here
const app = initializeApp(config);
// firebaseApps previously initialized using initializeApp()
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);
ufmemo's solution is correct.
A more detailed answer would be as follows.
// import 'firebase/auth';
import { connectAuthEmulator } from "firebase/auth";
if (process.env.NODE_ENV === "development"){
firebase.firestore().settings({ host: 'localhost:8080', ssl: false });
// firebase.auth().useEmulator('http://localhost:9099/');
connectAuthEmulator(firebase, 'http://localhost:9099/');
}
Related
My Firebase Function runs in the emulator and writes to the same collection and document:
import * as functions from "firebase-functions";
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return snap.ref.set({ uppercase }, { merge: true });
} catch (error) {
console.error(error);
}
});
That works great. Now I want to write to a different collection in the Firestore emulator:
import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
const firebaseConfig = {
apiKey: "...",
authDomain: "triggerable-functions-project.firebaseapp.com",
projectId: "triggerable-functions-project",
storageBucket: "triggerable-functions-project.appspot.com",
messagingSenderId: "...",
appId: "..."
};
const app = initializeApp(firebaseConfig);
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return db.firestore().collection('AnotherCollection').doc(context.params.docId).set({ uppercase }, { merge: true });
} catch (error) {
console.error(error);
}
});
That throws this error:
TypeError: db.firestore is not a function
I either have an incorrect Firestore DocumentReference or I didn't import a necessary module.
Let's write to Cloud Firestore. Same code, new module, different DocumentReference:
import * as admin from "firebase-admin";
...
return admin.firestore().collection('AnotherCollection').doc(context.params.docId).set({ uppercase }, { merge: true });
Same error:
TypeError: admin.firestore is not a function
Let's write to the Storage emulator:
import { getStorage, connectStorageEmulator, ref, uploadString } from "firebase/storage";
...
const storage = getStorage();
connectStorageEmulator(storage, "localhost", 9199);
...
return storage.collection('AnotherCollection').doc(context.params.docId).set({ uppercase }, { merge: true });
That throws the same error:
TypeError: storage.collection is not a function
Let's write to Cloud Storage:
const storageRef = ref(storage, 'Messages');
...
return uploadString(storageRef, uppercase);
The log says that the function executed without errors but when I go to Firebase Console I don't see the file in Cloud Storage.
Here's my final code. Why is app declared but never used?
import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
import { getStorage, connectStorageEmulator, ref, uploadString } from "firebase/storage";
import * as admin from "firebase-admin";
const firebaseConfig = {
apiKey: "...",
authDomain: "triggerable-functions-project.firebaseapp.com",
projectId: "triggerable-functions-project",
storageBucket: "triggerable-functions-project.appspot.com",
messagingSenderId: "...",
appId: "..."
};
const app = initializeApp(firebaseConfig);
const db = getFirestore();
connectFirestoreEmulator(db, 'localhost', 8080);
const storage = getStorage();
const storageRef = ref(storage, 'Messages');
connectStorageEmulator(storage, "localhost", 9199);
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return uploadString(storageRef, uppercase);
} catch (error) {
console.error(error); // emulator always throws an "unhandled error": "Your function timed out after ~60s."
}
});
You're using the new(ish) modular syntax of the v9 and later SDKs when you call getFirestore. With that new API, most calls are no longer namespaced, but are top-level functions. So there are no longer any public methods on the db object you have (as the error message says), but instead you have to pass the db object when calling those top-level functions.
The equivalent of this code:
db.firestore().collection('AnotherCollection').doc(context.params.docId).set({ uppercase }, { merge: true });
Would be:
setDoc(
doc(db, 'AnotherCollection', context.params.docId),
{ uppercase }, { merge: true })
)
Which is pretty close to the code sample in the documentation on setting a document with the v9 syntax, so I recommend keeping that handy while converting the rest of the code to the new API. The Upgrade from version 8 to the modular Web SDK guide is also a good place to get started, as are the blog posts Introducing the new Firebase JS SDK and The new Firebase JS SDK is now GA
Thanks, #Frank van Puffelen! Here's my Firebase version 9 code for writing to a different directory in the emulator:
import { initializeApp } from "firebase/app";
import * as functions from "firebase-functions";
import { getFirestore, connectFirestoreEmulator, setDoc, doc } from "firebase/firestore";
const firebaseConfig = {
apiKey: "...",
authDomain: "triggerable-functions-project.firebaseapp.com",
projectId: "triggerable-functions-project",
storageBucket: "triggerable-functions-project.appspot.com",
messagingSenderId: "...",
appId: "..."
};
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
connectFirestoreEmulator(db, 'localhost', 8080);
export const MakeUppercase = functions.firestore.document('Messages/{docId}').onCreate((snap, context) => {
try {
const original = snap.data().original;
const uppercase = original.toUpperCase();
return setDoc(
doc(db, 'AnotherCollection', context.params.docId),
{ uppercase }, { merge: true }
);
} catch (error) {
console.error(error);
}
});
Commenting out the emulator
connectFirestoreEmulator(db, 'localhost', 8080);
writes to Cloud Firestore. This threw an error:
Connection GRPC stream error. Code: 7 Message: 7 PERMISSION_DENIED: Missing or insufficient permissions.
I'm not going to worry about that, I presume that the emulator isn't intended to write to the Cloud.
As for Storage, my original code executes without errors but nothing writes to Storage in the emulator. Trying Cloud Storage, my Firebase Console refuses to set up Storage.
The documentation explains why I kept getting "not a function" errors. Instead of thinking of a Firestore location as a place with an address (in the namespace), in version 9 Firestore locations are functions with parameters.
While the version 8 APIs are based on a dot-chained namespace and
service pattern, version 9's modular approach means that your code
will be organized principally around functions.
David East explained in a blog post that the old (version 8) Firebase managed namespaces on the window but version 9 uses ES modules:
Historically libraries have been loaded and managed via a namespace on
the window, such as window.firebase. This technique does not allow for
tree shaking and lacks other benefits of the JavaScript module system.
I'm using my API key stored in a .env.local file. And it setup correctly but not working
assert.ts:128 Uncaught FirebaseError: Firebase: Error (auth/invalid-api-key).
at createErrorInternal (assert.ts:128:1)
at _assert (assert.ts:153:1)
at register.ts:67:1
at Component.instanceFactory (register.ts:90:1)
at Provider.getOrInitializeService (provider.ts:318:1)
at Provider.initialize (provider.ts:242:1)
at initializeAuth (initialize.ts:66:1)
at getAuth (index.ts:44:1)
at Module../src/firebase.init.js (firebase.init.js:22:1)
at Module.options.factory (react refresh:6:1)
I don't know why React is giving me an error. I intialized firebase in the following file
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: process.env.REACT_APP_apiKey,
authDomain: process.env.REACT_APP_authDomain,
projectId: process.env.REACT_APP_projectId,
storageBucket: process.env.REACT_APP_storageBucket,
messagingSenderId: process.env.REACT_APP_messagingSenderId,
appId: process.env.REACT_APP_appId,
measurementId:process.env.REACT_APP_measurementId
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
export default auth;
It is likely that you are having multiple render of your app. Do it this way:
const firebaseConfig = {
apiKey: process.env.REACT_APP_apiKey || 'test',
authDomain: process.env.REACT_APP_authDomain || 'test',
projectId: process.env.REACT_APP_projectId || 'test',
storageBucket: process.env.REACT_APP_storageBucket || 'test',
messagingSenderId: process.env.REACT_APP_messagingSenderId || 'test',
appId: process.env.REACT_APP_appId || 'test',
measurementId:process.env.REACT_APP_measurementId || 'test'
};
In that case at the first render, when the environment variables are yet available, you will have default values, not null or undefined values.
I hope it helps someone.
yesterday my application had no problems when it wanted to request fcm tokens, suddenly now it can't, and the error that appears is:
error result
my assumption is because firebase-messaging-sw can't be active, it's not even in the build result folder, even though yesterday there was no problem at all. the firebase I'm using is version 9 so it's modular.
firebase-messaging-sw.js
import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging/sw";
// Initialize the Firebase app in the service worker by passing in
// your app's Firebase config object.
// https://firebase.google.com/docs/web/setup#config-object
const firebaseApp = initializeApp({
apiKey: "--------",
authDomain: "-------",
projectId: "------",
storageBucket: "-----",
messagingSenderId: "------",
appId: "---------"
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = getMessaging(firebaseApp);
main.js
import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import { initializeApp } from "firebase/app";
import './utils/firebase-messaging-sw'
import { getMessaging, getToken } from "firebase/messaging";
const firebaseConfig = {
apiKey: "---------------------",
authDomain: "-----------------------",
projectId: "---------------------",
storageBucket: "----------------------",
messagingSenderId: "-----------------------",
appId: "---------------------------"
};
const app = initializeApp(firebaseConfig);
const messaging = getMessaging();
getToken(messaging, { vapidKey: '---------------------------------' }).then((currentToken) => {
if (currentToken) {
console.log(currentToken)
} else {
console.log('No registration token available. Request permission to generate one.');
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
});
createApp(App).use(store).use(router).mount('#app')
after build the firebase-messaging-sw.js file should also be in it, that's what happened yesterday, but somehow now suddenly it can't
build result
because i use pwa, there should be 2 active service workers
service worker from Vue
service worker from firebase-messaging-sw
in fact the only active ones are vue's service workers
active service workers
here is my directory structure
directory
I am getting the following error: Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: FirebaseError: [code=permission-denied]: Permission denied on resource project disneyplus-clone-a33d5.
I am learning React and the tutorial I am learning from uses firebase. I have very little knowledge about firebase. I cannot find any solution for this error. here is my fbconfig.js :
import { initializeApp } from 'firebase/app';
import { getAuth, GoogleAuthProvider } from "firebase/auth";
import { getStorage } from "firebase/storage";
import { getFirestore } from "firebase/firestore"
const firebaseConfig = {
apiKey: "---",
authDomain: "--.firebaseapp.com",
projectId: "--",
storageBucket: "--",
messagingSenderId: "--",
appId: "--",
measurementId: "---",
};
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
const auth = getAuth();
const provider = new GoogleAuthProvider();
const storage = getStorage(firebaseApp);
export { auth, provider, storage };
export default db;
Here is my Home.js :
import db from '../fbconfig'
import { doc, onSnapshot, collection, query, where } from "firebase/firestore";
function Home() {
useEffect(() => {
const q = query(collection(db, "movies"))
const unsub = onSnapshot(q, (snapshot)=>{
let tempMovies = snapshot.docs.map((doc)=>{
console.log(doc.data());
return { id: doc.id, ...doc.data() }
})
});
code=permission-denied when working with Firestore is always a permissions problem on the collection you are trying to read, in this case "movies". To set permissions on a collection you can use the Firebase web gui or the command line tools.
The specific rule you will need for read access to "movies" is
match /movies {
allow get: if true;
allow list: if true;
allow update: if false;
allow create: if false;
allow delete: if false;
}
https://firebase.google.com/docs/rules/manage-deploy
Or the web ui
I am trying to get my datas from firebase with console log but i am getting an error.
The error is: image
This is my database: https://i.stack.imgur.com/A1zYm.png
<script type="module">
import {
initializeApp
} from "https://www.gstatic.com/firebasejs/9.4.0/firebase-app.js";
import {
getDatabase,
set,
ref,
update
} from "https://www.gstatic.com/firebasejs/9.4.0/firebase-database.js";
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
onAuthStateChanged,
signOut
} from "https://www.gstatic.com/firebasejs/9.4.0/firebase-auth.js";
const firebaseConfig = {
apiKey: ,
authDomain: ,
databaseURL: ,
projectId: ,
storageBucket: ,
messagingSenderId: ,
appId: ,
measurementId:
};
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);
const auth = getAuth();
const firebaseRef = firebase.database().ref("Users");
firebaseRef.once("value", function(snapshot) {
snapshot.forEach(function(element) {
console.log(element);
})
});
</script>
You're trying to use the old v8 syntax with Firebase SDK 9, which won't work. You'll either have to use the new modular syntax, or import the older SDKs or the compatibility versions on v9.
In v9 syntax, getting a reference to and reading a value from the database is done with:
import { getDatabase, ref, get } from "firebase/database";
...
const database = getDatabase();
const firebaseRef = ref(database, "Users");
get(firebaseRef, function(snapshot) {
snapshot.forEach(function(element) {
console.log(element);
})
});
For more examples, see the Web version 9 (modular) tabs in the documentation I linked above, and the upgrade guide specifically the section on upgrading with the compat libraries.