Firebase storage/retry-limit-exceeded error - reactjs

I have problem with my app. It's based on electron + react boilerplate. I tried to link Firebase Storage to let user download files, but I can't make it work.
Everytime when I try to make any operation on the storage (list files, getDownloadURL, download file, upload file) I get error:
Firebase.tsx:31 Uncaught (in promise) FirebaseError: Firebase Storage: Max retry time for operation exceeded, please try again. (storage/retry-limit-exceeded)
So far my code looks like this for debug:
import { initializeApp } from 'firebase/app';
import { getStorage, ref, getDownloadURL} from 'firebase/storage';
const firebaseConfig = {
apiKey:
authDomain: ...
projectId: ...
storageBucket: ...
messagingSenderId:...
appId:...
};
const app = initializeApp(firebaseConfig);
const storage = getStorage(app);
const file = ref(storage, '/maps/122.png');
async function getURL() {
let data = await getDownloadURL(file);
console.log(data);
}
function Firebase() {
return <button onClick={() => getURL()}>Click</button>;
}
After I click on the button I wait for about few seconds and this error shows in console.
Tried different functions
Tried different arguments
Read docs and copy paste the original code
Tried to change rules for allow all
Check the retry limit value and it's default

Related

NextJS/Firebase - implementing firebase analytics throw error: Missing App configuration value

i am using Next JS 13 with default pages directory and i use database for my project. Everything works fine, until i started to implementing firebase analytics.
First it throwed that window is undefiend. I solved it by checking window. After that it worked so i wanted to test logEvent() function in my index.js page.
And it throw FirebaseError: Installations: Missing App configuration value: "projectId" (installations/missing-app-config-values).
I tried to use proccess.env.NEXT_PUBLIC but it didnt worked.
import { initializeApp} from 'firebase/app';
import { getFirestore } from 'firebase/firestore';
import { getStorage } from 'firebase/storage';
import { getAnalytics } from 'firebase/analytics';
const firebaseConfig = {
apiKey: process.env.API_KEY,
authDomain: process.env.AUTH_DOMAIN,
projectId: process.env.PROJECT_ID,
storageBucket: process.env.STORAGE_BUCKET,
messagingSenderId: process.env.MESSAGING_SENDER_ID,
appId: process.env.APP_ID,
measurementId: process.env.MEASUREMENT_ID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
export const db = getFirestore(app);
export const storage = getStorage(app);
export const analytics = typeof window !== 'undefined' ? getAnalytics(app) : null;
export default app;
Index.js example
<Button
key={`${name}_${index}`}
href={url}
mouseEnter={() => selectedImg !== img && handleMouseEnter(img)}
customStyles={'py-5 bg-primary-blue/60'}
onClick={() => (analytics ? logEvent(analytics, name) : {})}
> Test </Button>
Have someone similiar problem and solved it?
As the error says, the 'appId' is missing in your config object. You could try to copy it again in the Firebase Console to make sure you're using the updated one.
SOLVED: There was problem that i was using .env file, but in next js env variables should be inside next.config so it will load during build time.

Firestore arrayUnion returns FirebaseError: Function DocumentReference.update() called with invalid data

I am trying to update an array in firestore with React and node Firebase SDK (not the admin SDK) using the arrayUnion and I get an error that reads:
FirebaseError: Function DocumentReference.update() called with invalid data. Unsupported field value: undefined (found in field requestIDs in document usernames/tester/projects/default)
For the life of me I have not been able to figure out what why I am getting this error as my code will update the value without using the arrayUnion so it is fielding the location. I have tried the other similar asked questions and have not gotten it to work.
some code:
firebase.js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';
const firebaseConfig = {
apiKey: xxxx,
authDomain: "xxxx.firebaseapp.com",
projectId: "xxxxx",
storageBucket: "xxxxx.appspot.com",
messagingSenderId: "xxxxx",
appId: "xxxxxx",
measurementId: "xxxxxx"
};
// initialize Firebase
if (!firebase.apps.length)
{
firebase.initializeApp(firebaseConfig);
}
else
{
firebase.app(); // if already initialized, use this one
}
export const auth = firebase.auth()
export const firestore = firebase.firestore();
export default firebase
export const storage = firebase.storage();
export const serverTimestamp = firebase.firestore.FieldValue.serverTimestamp;
export const arrayUnion=(data) =>{
firebase.firestore.FieldValue.arrayUnion(data);
}
export const TimestampToDate = firebase.firestore.Timestamp.toDate;
commissions.services.js file
import { firestore, arrayUnion } from "../firebase";
// get ref to projects
const getProjectRef = (username) =>{
return firestore.collection('usernames').doc(username).collection('projects').doc('default');
};
// add docID to requestIDs array
const updateProjectColumns= (id, username ) =>{
return getProjectRef(username).update({'requestIDs': arrayUnion(id)});
}
const CommissionService = {
updateProjectColumns
};
export default CommissionService;
ButtonRequest.js
import CommissionService from '../../services/commissions.service';
// relevant code
const handleClick = () => {
CommissionService.updateProjectColumns(props.docID, props.requestData.data().commissionedArtist);
};
My CommissionService.updateProjectColumns is the problem. The props are working and if I substitute a test string for the the [arrayUnion(id)] portion it will update the document just erasing the array that was already there with the string.
All the docs on Firestore say that this is the way to use the arrayUnion function. Even if that field value was not an array, according to the docs, the function should make it an array with only the added value.
sample doc in firestore
requestIDs: [
"test String"
]
docs are here : https://firebase.google.com/docs/firestore/manage-data/add-data?authuser=2#node.js_11
The only difference I can see is that I am not using the admin SDK but the function seems the same in the client side SDK. Any help would be appreciated.
Probably because:
export const arrayUnion=(data) =>{
firebase.firestore.FieldValue.arrayUnion(data);
}
...has no return statement. So I think you want...
export const arrayUnion=(data) =>{
return firebase.firestore.FieldValue.arrayUnion(data);
}
To generalize (in case data has more than one value, like an array) you may want to do:
export const arrayUnion=(data) =>{
return firebase.firestore.FieldValue.arrayUnion(...data);
}

"firebase.auth.EmailAuthProvider.credential" is undefined (React Native)

I've been working on my first React Native project using Firebase Auth (plain email&password only).
Signing-in, Signing-out, Resetting passwords, etc... everything is fine, but I'm stuck with one thing and I need help with deleting user.
Because deleting user is a "sensitive" request, Firebase Auth demands re-authenticating the user before actually deleting the user.
This is where I can't figure out how to do it. Even the docs don't tell much. They literally say: "TODO(you): prompt the user to re-provide their sign-in credentials".
ErrorMessage :
TypeError: undefined is not an object (evaluating '_firebase.auth.EmailAuthProvider.credential')
My firebase.js :
import firebase from 'firebase';
const firebaseConfig = { //key hidden here for security reasons
apiKey: apiKey,
authDomain: authDomain,
projectId: projectId,
storageBucket: storageBucket,
messagingSenderId: messagingSenderId,
appId: appId,
measurementId: measurementId
};
const app = !firebase.apps.length
? firebase.initializeApp(firebaseConfig)
: firebase.app();
const db = app.firestore();
const auth = firebase.auth();
export {db, auth};
My component.js :
...
import { auth } from '../firebase/firebase';
...
const deleteUser = () => {
const user = auth.currentUser;
const credential = auth.EmailAuthProvider.credential(userEmail,userProvidedPassword);
user.reauthenticateWithCredential(credential).then(() => {
user.delete().then(() => {
auth.signOut();
}).catch((error) => {
console.log(error.message);
});
}).catch((error) => {
console.log(error.message);
});
}
You cannot delete users from the front-end React Native!
Instead, there is firebase admin SDK which allows you to delete users but it has to be done from the backend. I believe this link to Firebase Admin SDK will answer your questions.
Also, do check Firebase Cloud Functions if you don't have a backend and you are just relying on Firebase.
Cloud Functions allows you to create a function in Firebase that you can call from React Native using Firebase SDK and perform delete user operation also you could watch for a collection and send notification and do more stuff!
And it is simple than it sounds!

Firebase and reactjs: Firebase App named '[DEFAULT]' already exists (app/duplicate-app) [duplicate]

I started a project and occurred an error when importing firebase in more than one component.
In this firebase start file:
import firebase from 'firebase'
const firebaseConfig = {
apiKey: "fdsfsdfdsf",
authDomain: "fdsfdsfsdfdsf",
databaseURL: "sdfdsfdsf",
projectId: "dsfdsfdsf",
storageBucket: "dsfdsfdsf",
messagingSenderId: "dsfdsfsdfdsf"
}
const FbApp = firebase.initializeApp(firebaseConfig)
export default FbApp.auth()
Then in the components:
import firebase from '../lib/firebaseClient'
With a single component works well, but if I add a new component with:
import firebase from '../lib/firebaseClient'
The application fail:
FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
I had same issue, then I found out this:
if (!firebase.apps.length) {
firebase.initializeApp({});
}
https://github.com/zeit/next.js/issues/1999
The solution:
import firebase from 'firebase'
try {
firebase.initializeApp({
databaseURL: 'dfgdfg'
})
} catch (err) {
// we skip the "already exists" message which is
// not an actual error when we're hot-reloading
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
const auth = firebase.auth()
export default auth
My understanding is that the error is due to calling initializeApp() more than once for your database. Scan through your code to make sure you only call initializeApp() once. For me, this included checking any js files that might be calling the method and checking for duplicate js files in your html file.
I recently solved this error in my own code. My issue was caused by accidentally linking my javascript file, which calls initializeApp(), in the head and in the body of my html file. My fix was to delete the duplicate javascript tag in the head of my html file so only one existed in the body.
On serverside something like this should work
const admin = require('firebase-admin');
const serviceAccount = require('./../../credentials/server');
// Check if firebase already been initialized
if (!admin.apps.length) {
// Initialize Firestore.
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
}
Summarizing all good answers.
A better fix would be to load environment variables from .env.local into process.env.
//.env.local
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
Next up, we can initialize the Firebase SDK on the client-side like this.
//shared/configs/firebase.js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
const clientCredentials = {
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,
};
if (!firebase.apps.length) {
firebase.initializeApp(clientCredentials);
}
export default firebase;
Finally, import the Firebase deps to other file.
//pages/index.js
import firebase from '../shared/configs/firebase';
So I ran into this issue because of some aspect of Next's hot reloading. I was using code like the following to ensure that I didn't call initializeApp more than once:
export let adminClient;
adminClient = adminClient || admin.initializeApp({...});
This didn't work because it seemed like the hot reloading was clearing adminClient, so I kept trying to call initializeApp, even though firebase still had the app recorded as being initialized.
To fix this, I used the following snippet:
const getAppInstance = () => {
if (admin.apps.length) {
return admin.apps[0];
} else {
return initApp();
}
}
export const adminClient = getAppInstance();
which works on a fresh server start, or when hot reloading due to code changes in development.
If you are using a new Modular SDK v9.0.1 then it might not support the "firebase" namespace.
The Implementation, I used
import { initializeApp, getApps } from "firebase/app"
import { getFirestore } from "firebase/firestore"
import { getAuth } from "firebase/auth"
//App configure
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_MESSAGGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_MEASUREMENT_ID
};
if (!getApps().length) {
console.log(`...`)
}
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)
const auth = getAuth(app)
export {db, auth}
export default app
Reference:
StackOverflow: Visit
Firebase Docs: Visit
Firebase Tutorial Setup: Visit

React NextJS Firebase error refresh Firebase App named '[DEFAULT]' already exists

I started a project and occurred an error when importing firebase in more than one component.
In this firebase start file:
import firebase from 'firebase'
const firebaseConfig = {
apiKey: "fdsfsdfdsf",
authDomain: "fdsfdsfsdfdsf",
databaseURL: "sdfdsfdsf",
projectId: "dsfdsfdsf",
storageBucket: "dsfdsfdsf",
messagingSenderId: "dsfdsfsdfdsf"
}
const FbApp = firebase.initializeApp(firebaseConfig)
export default FbApp.auth()
Then in the components:
import firebase from '../lib/firebaseClient'
With a single component works well, but if I add a new component with:
import firebase from '../lib/firebaseClient'
The application fail:
FirebaseError: Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
I had same issue, then I found out this:
if (!firebase.apps.length) {
firebase.initializeApp({});
}
https://github.com/zeit/next.js/issues/1999
The solution:
import firebase from 'firebase'
try {
firebase.initializeApp({
databaseURL: 'dfgdfg'
})
} catch (err) {
// we skip the "already exists" message which is
// not an actual error when we're hot-reloading
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
const auth = firebase.auth()
export default auth
My understanding is that the error is due to calling initializeApp() more than once for your database. Scan through your code to make sure you only call initializeApp() once. For me, this included checking any js files that might be calling the method and checking for duplicate js files in your html file.
I recently solved this error in my own code. My issue was caused by accidentally linking my javascript file, which calls initializeApp(), in the head and in the body of my html file. My fix was to delete the duplicate javascript tag in the head of my html file so only one existed in the body.
On serverside something like this should work
const admin = require('firebase-admin');
const serviceAccount = require('./../../credentials/server');
// Check if firebase already been initialized
if (!admin.apps.length) {
// Initialize Firestore.
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
}
Summarizing all good answers.
A better fix would be to load environment variables from .env.local into process.env.
//.env.local
NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=
Next up, we can initialize the Firebase SDK on the client-side like this.
//shared/configs/firebase.js
import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
const clientCredentials = {
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,
};
if (!firebase.apps.length) {
firebase.initializeApp(clientCredentials);
}
export default firebase;
Finally, import the Firebase deps to other file.
//pages/index.js
import firebase from '../shared/configs/firebase';
So I ran into this issue because of some aspect of Next's hot reloading. I was using code like the following to ensure that I didn't call initializeApp more than once:
export let adminClient;
adminClient = adminClient || admin.initializeApp({...});
This didn't work because it seemed like the hot reloading was clearing adminClient, so I kept trying to call initializeApp, even though firebase still had the app recorded as being initialized.
To fix this, I used the following snippet:
const getAppInstance = () => {
if (admin.apps.length) {
return admin.apps[0];
} else {
return initApp();
}
}
export const adminClient = getAppInstance();
which works on a fresh server start, or when hot reloading due to code changes in development.
If you are using a new Modular SDK v9.0.1 then it might not support the "firebase" namespace.
The Implementation, I used
import { initializeApp, getApps } from "firebase/app"
import { getFirestore } from "firebase/firestore"
import { getAuth } from "firebase/auth"
//App configure
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_MESSAGGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_MEASUREMENT_ID
};
if (!getApps().length) {
console.log(`...`)
}
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)
const auth = getAuth(app)
export {db, auth}
export default app
Reference:
StackOverflow: Visit
Firebase Docs: Visit
Firebase Tutorial Setup: Visit

Resources