firebase v9 error could not reach cloud firestore backend nuxtjs - firebase

Firebase v9 is acting weird I think, I have on my code:
async nuxtServerInit({ commit }) {
try {
const dryers = await getDocs(collection(db, "dryers"))
const payload = dryers.docs.map(item => {
return {
docId: item.id,
...item.data()
}
})
commit("LOAD_DRYERS", payload)
} catch (err) {
console.error(err.message || "Could not process the request, something went wrong.")
}
}
This is part of my vuex actions that should trigger on init, it is working fine in this part, the code is populated to the state, but the problem is, whenever I load data on click event, i.e:
<button #click.prevent="testQuery">Test query</button>
...
async testQuery() {
try {
const x = await getDocs(collection(db, "dryers"))
console.log(x)
} catch (err) {
console.error(err)
}
}
the weird thing is, when testQuery is executed, I get a could not reach cloud firestore backend error response, when in fact, a successful query is made during init.
here's my config:
import { initializeApp } from 'firebase/app'
import { initializeAuth, getAuth } from "firebase/auth"
import { initializeFirestore } from "firebase/firestore"
const firebaseConfig = {
apiKey: process.env.apiKey,
authDomain: process.env.authDomain,
projectId: process.env.projectId,
storageBucket: process.env.storageBucket,
messagingSenderId: process.env.messagingSenderId,
appId: process.env.appId,
measurementId: process.env.measurementId
}
// Initialize Firebase
const app = initializeApp(firebaseConfig)
initializeAuth(app)
const auth = getAuth(app)
const db = initializeFirestore(app, {
experimentalForceLongPolling: true
})
export { auth, db }
I'm using firebase v9.1.2, any tips?

Related

Service messaging is not available

I want to integrate FCM with nextjs project.
This error is occurring whenever I save the firebase.js config file. I'm not being able to use Firebase Cloud Messaging in Firebase V9.
I use firebase 9.10.0
my firebase.js config
import { initializeApp } from 'firebase/app';
import { getToken, getMessaging, onMessage } from 'firebase/messaging';
const firebaseConfig = {
apiKey: "*************",
authDomain: "********************",
projectId: "******************",
storageBucket: "*****************",
messagingSenderId: "*************",
appId: "**********************"
};
console.log('*** Environment ***', process.env.REACT_APP_ENV)
console.log('*** Firebase Config ***', firebaseConfig)
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
export const getOrRegisterServiceWorker = () => {
if ('serviceWorker' in navigator) {
return window.navigator.serviceWorker
.getRegistration('/firebase-push-notification-scope')
.then((serviceWorker) => {
if (serviceWorker) return serviceWorker;
return window.navigator.serviceWorker.register('/firebase-messaging-sw.js', {
scope: '/firebase-push-notification-scope',
});
});
}
throw new Error('The browser doesn`t support service worker.');
};
export const getFirebaseToken = () =>
getOrRegisterServiceWorker()
.then((serviceWorkerRegistration) =>
getToken(messaging, { vapidKey: "***********", serviceWorkerRegistration }));
export const onForegroundMessage = () =>
new Promise((resolve) => onMessage(messaging, (payload) => resolve(payload)));
Ather searing a lot I found solutions:
I change the code of my firebase.js file to the below code
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getMessaging, getToken } from "firebase/messaging";
import localforage from "localforage";
const firebaseConfig = {
apiKey: "**********************",
authDomain: "*******************",
projectId: "******************",
storageBucket: "****************",
messagingSenderId: "****************",
appId: "**************"
};
// Initialize Firebase
const firebaseCloudMessaging = {
init: async () => {
initializeApp(firebaseConfig);
try {
const messaging = getMessaging();
const tokenInLocalForage = await localStorage.getItem("fcm_token");
// Return the token if it is alredy in our local storage
if (tokenInLocalForage !== null) {
return tokenInLocalForage;
}
// Request the push notification permission from browser
const status = await Notification.requestPermission();
if (status && status === "granted") {
// Get new token from Firebase
const fcm_token = await getToken(messaging, {
vapidKey:
"********************",
});
console.log("token in fcm_token", fcm_token);
// Set token in our local storage
if (fcm_token) {
localforage.setItem("fcm_token", fcm_token);
return fcm_token;
}
}
} catch (error) {
console.error(error);
return null;
}
},
};
export { firebaseCloudMessaging };

Can we make firebase actions serializable for redux toolkit?

I am using react and redux toolkit in a project. I also use firebase to manage authentication for this project.
I'm dispatching an async thunk that I call login to login users. And here I am calling the signInWithEmailAndPassword method of firebase. I export this method from a file named firebase.ts. You can find code snippets below.
// firebase.ts
import { initializeApp } from "firebase/app";
import {
getAuth,
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
sendPasswordResetEmail,
sendEmailVerification,
updateEmail,
updatePassword,
reauthenticateWithCredential,
EmailAuthProvider,
} from "firebase/auth";
const firebaseConfig = {
apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_FIREBASE_APP_ID,
measurementId: process.env.REACT_APP_FIREBASE_MEASUREMENT_ID,
};
const firebaseApp = initializeApp(firebaseConfig);
export const auth = getAuth(firebaseApp);
export {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
signOut,
sendPasswordResetEmail,
sendEmailVerification,
updateEmail,
updatePassword,
reauthenticateWithCredential,
EmailAuthProvider,
};
// UserContent/thunks.ts
import { createAsyncThunk } from "#reduxjs/toolkit";
import { auth, signInWithEmailAndPassword, signOut } from "#app/api/firebase";
import { UserLoginForm } from "#common/formTypes";
export const login = createAsyncThunk(
"userContent/login",
async (data: UserLoginForm) => {
const { email, password } = data;
const response = await signInWithEmailAndPassword(auth, email, password);
return response;
}
);
export const logout = createAsyncThunk("userContent/logout", async () => {
const response = await signOut(auth);
return response;
});
But as you can guess in the console, I get a warning like the following.
Console Warning Image
Of course I know I can turn off this warning very easily. But is there a better way to solve this?
You can convert your response to a serializable object by adding .toJson() to the response.
export const login = createAsyncThunk(
"userContent/login",
async (data: UserLoginForm) => {
const { email, password } = data;
const response = await signInWithEmailAndPassword(auth, email, password);
return response.toJSON();
}
);

Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK. [Firebase Auth on NextJS App]

I'm trying to deploy my NextJS App on Vercel. But I'm getting this error.
Also, my project runs smoothly in development mode, but why am I getting such an error while deploying?
Firebase.ts File
import { initializeApp } from "firebase/app";
import {
getAuth,
signInWithEmailAndPassword,
onAuthStateChanged,
signOut,
} from "firebase/auth";
import { handlerSetUser } from "./utils";
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
onAuthStateChanged(auth, (user: any) => {
if (user) {
handlerSetUser(user);
} else {
handlerSetUser(false);
}
});
export const login = async (email: any, password: any) => {
try {
const result = await signInWithEmailAndPassword(auth, email, password);
return result;
} catch (error: any) {
alert(error.message);
}
};
export const logout = async () => {
try {
await signOut(auth);
} catch (error: any) {
alert(error.message);
}
};
Vercel Deployment Error
_errorFactory: ErrorFactory {
service: 'auth',
serviceName: 'Firebase',
errors: {
'dependent-sdk-initialized-before-auth': 'Another Firebase SDK was initialized and is trying to use Auth before Auth is initialized. Please be sure to call `initializeAuth` or `getAuth` before starting any other Firebase SDK.'
}
},

Firestore works once and then it keeps throwing this error

I am trying to use this to get a snapshot of the firestore in a Nextjs project. But for some reason it works the first time but as soon as I refresh the page I get the following error and then I have to restart the server.
[FirebaseError: Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore] {
code: 'invalid-argument',
customData: undefined,
toString: [Function (anonymous)]
}
import db from "../../firebase";
import { collection, getDocs, orderBy, query } from "firebase/firestore";
export async function getServerSideProps(context) {
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const session = await getSession(context);
//query from firestore
const colRef = collection(db, `users/${session.user.email}/orders`);
const q = query(colRef, orderBy("timestamp", "desc"));
const snapshot = await getDocs(q);
The db instance is imported from the firebase config file here.
import { getApp, initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
const firebaseConfig = {
apiKey: "some-apikey",
authDomain: "some-authDomain",
projectId: "some-projectId",
storageBucket: "some-storageBucket",
messagingSenderId: "some-messagingSenderId",
appId: "some-appId",
measurementId: "some-measurementId",
};
function createFirebaseApp(config) {
try {
return getApp();
} catch {
return initializeApp(config);
}
}
const app = createFirebaseApp(firebaseConfig);
const db = getFirestore(app);
export default db;
The query returns the correct data the first time but the second time the error appears. I have also tired with firebase/firestore/lite but the same error appears

How to configure firebase as nuxt plugin?

I am trying to configure firebase in nuxt as a plugin. I have to make the nuxtInitServer call in store because the env variables are from sharedEnv.
When the login method is invoked on the login page, I get the error:
Uncaught TypeError: _plugins_firebase__WEBPACK_IMPORTED_MODULE_3__.default.auth is not a function
store/index.js
const getSharedEnv = () =>
process.server
? {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
databaseURL: process.env.FIREBASE_DB_URL,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGE_SENDER_ID
}
: {}
...
export const actions = {
nuxtServerInit({ commit, state, store, dispatch }, { req }) {
if (process.server) {
commit('setSharedEnv', getSharedEnv())
}
}
}
plugins/firebase.js
import Vue from 'vue'
import firebase from 'firebase/app'
Vue.use(firebase)
export default context => {
// perform a store action manually to have access to `sharedEnv` object
context.store.dispatch('nuxtServerInit', context)
const env = { ...context.store.state.sharedEnv }
if (!firebase.apps.length) {
console.log('initialize firebase...')
firebase.initializeApp(env)
}
return firebase
}
pages/login/index.vue
<script>
import firebase from '#/plugins/firebase'
export default {
name: 'login',
data() {
return {
email: '',
password: ''
}
},
methods: {
login: function() {
let additionalClaims = {
premiumAccount: true
}
console.log('login page')
console.log(firebase)
firebase
.auth()
.signInWithEmailAndPassword(this.email, this.password)
.then(
response => {
...
You need to also import the firebase/auth library if you need the auth feature
i.e.
import firebase from 'firebase/app';
import 'firebase/auth';

Resources