undefined is not an object firebase.auth.FacebookAuthProvider.credential - javascript

Here is my code.. its pretty simple.. just trying to allow a user to authenticate through facebook and then add it to the Firebase system!
I should mention that I am using React Native, I did read that various parts of the Firebase library does not work with React Native.
const auth = firebase.auth();
const provider = firebase.auth.FacebookAuthProvider;
LoginManager.logInWithReadPermissions(['public_profile'])
.then(loginResult => {
alert("login results")
if (loginResult.isCancelled) {
alert('user canceled');
return;
}
AccessToken.getCurrentAccessToken()
.then(accessTokenData => {
const credential = firebase.auth.FacebookAuthProvider.credential(accessTokenData.accessToken);
alert("Credential: " + credential )
return auth.signInWithCredential(credential);
})
.then(credData => {
console.log(credData);
alert("CRED data:::" + credData)
alert(firebase)
})
.catch(err => {
console.log(err);
alert("ERROR:::" + err)
alert(firebase)
});
});
The only reasoning I can really think of for this is that Firebase is undefined or it does not finish initializing.. although it seems to be.. maybe I can put in some sort of promise to ensure it has initialized.
(Any ideas on how to do that?)
Although firebase seems to be initalized.. but I went through the api reference and can't really find any reason why .auth.FacebookAuthProvider.credential would not exist
Any help would be great!

I was having this exact same issue, and I have a solution that worked for me, but I'm not sure if it will be the same for you.
I was instantiating my firebase class through a separate module, in a file called FirebaseService.js
'use-strict';
const firebase = require('firebase');
const APP_BASE = 'https://your-unique-url.firebaseapp.com/'
const FIREBASE_CONFIG = {
apiKey: '[super_unique]',
authDomain: 'your-unique-url.firebaseapp.com',
databaseURL: APP_BASE,
storageBucket: 'your-unique-url.appspot.com',
};
export const Firebase = firebase.initializeApp(FIREBASE_CONFIG);
I was then using it everywhere else in my code by importing it:
const { Firebase } = require ('./services/FirebaseService');
This appeared to be fine until I got around to implementing facebook login, and that's when I started having the same issue.
I had to import firebase in the screen that was trying to login with facebook. instead of requiring my own service, I used the npm module:
const firebase = require('firebase');
After that, I was able to access FacebookAuthProvider.credential. I'm really not sure why this is the case, there may have been something wrong with my use of modules

Related

Firebase problem "Uncaught (in promise) ReferenceError: exports is not defined"

I'm trying to create a new document when a user signs up for my app.
However, 'exports' is returning "Uncaught (in promise) ReferenceError: exports is not defined".
The code below is handling the function. I do also have an onAuthStateChanged function that switches some logged-in/out elements, although I don't think that could be stopping exports from being defined.
import { createUserWithEmailAndPassword, onAuthStateChanged,
signInWithEmailAndPassword } from "firebase/auth";
import { db, auth } from "./firebase";
import { collection, doc, setDoc, addDoc } from "firebase/firestore";
const signUpForm = document.querySelector('#signup-form');
if (signUpForm) {
signUpForm.addEventListener('submit', (e) => {
e.preventDefault();
//get user info
const email = signUpForm['signup-email'].value;
const password = signUpForm['signup-password'].value;
createUserWithEmailAndPassword(auth, email, password).then((cred) => {
const overlay = document.getElementById('overlay');
overlay.classList.add('hidden');
overlayP.classList.remove('hidden');
signUpForm.reset();
exports.createUserDoc = functions.auth.user().onCreate((user) => {
return admin.firestore().collection("users").doc(user.uid).setDoc({
email: user.email,
uid: user.uid,
})
});
// document.getElementById("signUpErr").innerHTML = "";
})
// .catch(err => {
// document.getElementById("signUpErr").innerHTML = err.message;
// });
});
};
I have initialized firebase and installed express.js within my index.js file but am I missing something to make sure this parameter is defined? I'm using Vite as a package bundler and node.js.
I'm new to coding and firebase, any advice would be massively appreciated.
I managed to solve this issue by taking a few days to read the documentation and understand what is going on with Cloud functions. The benefit of having a cloud function is that you can create triggers to your database that is away from your client-side code, improving security.
I was trying to call the cloud function within my app.js file and not within the firestore functions index.js file created when initializing firebase. Here you import through CommonJS Modules (CJS) the required SDK, in my case it was functions and admin.
Now my cloud functions live within index.js in /Functions folder separate from my app files.
// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
I also had to change the .setDoc() function to .set() as this was a Type error. I also added a userDelete function to delete users' documents in firestore.
exports.createUserDoc = functions.auth.user().onCreate(user => {
// Your new auth record will have the uid and email on it because
// you used email as the way to create the auth record
return admin.firestore().collection("users").doc(user.uid).set({
email: user.email,
bookmarked: []
})
});
exports.userDeleted = functions.auth.user().onDelete(user => {
const doc = admin.firestore().collection("users").doc(user.uid);
return doc.delete();
});
I would also like to note that setting up the firestore emulator has been very useful in this process and I'm sure will help me develop and test the other functions I need to create my app.

'Cannot read property 'apps' of undefined' in nuxtJs/ firebase

I have tried to integrate firebase with Nuxt Js and i am getting this error
As per documentation first I have installed firebase with help of "npm install firebase" and then i have installed "npm install #nuxtjs/firebase" and third i have integrated my firebase config in modules in nuxt.config.js
so whats the solution to solve the above error?
Thanks in advance
It depends on which version of #nuxtjs/firebase you are using, because this package #nuxtjs/firebase is not compatible with firebase version 9+ supporting tree-shaking.
So you need to downgrade you package to firebase version 8 and prior.
For more information, please check the authors github issues.
If you are using the new Modular SDK v9.0.1 you might get the above error as it does not use firebase. namespace now,
Try using getApps() instead of firebase.apps.
import { initializeApp, getApps } from "firebase/app"
import { getFirestore } from "firebase/firestore"
import { getAuth } from "firebase/auth"
const firebaseConfig = {...}
if (!getApps().length) {
//....
}
const app = initializeApp(firebaseConfig)
const db = getFirestore(app)
const auth = getAuth(app) export {db, auth}
I banged my head against this problem for a while - I was trying to use the Realtime Database in a dynamic page and getting the same error. I finally went back to this issue on the firebase module repo. Basically I had to do two things:
use the async asyncData method instead of just defining data properties; and
use both the app and params variables.
So instead of this:
export default {
data: () => ({
items: []
)},
async fetch ({ params }) {
const ref = this.$fire.database.ref(`foo/${params.slug}`)
const data = (await ref.once('value')).val()
this.items = data
}
}
I had to do this:
export default {
async asyncData ({ app, params }) {
const ref = app.$fire.database.ref(`foo/${params.slug}`)
const data = (await ref.once('value')).val()
return { items: data }
}
}

Firebase Realtime Database - "Error: Client is offline". React/NextJS

Using React with NextJS the following error occurs occasionally when fetching data from a Firebase Realtime Database.
Unhandled Runtime Error
Error: Error: Client is offline.
I am using Firebase 9.0.1 for React.
Top Level code for intialisation and config
import { initializeApp } from "firebase/app";
import { getDatabase, ref, onValue, child, get } from "firebase/database";
import CONFIG from '../CONFIG.json'
const FIREBASE_CONFIG = {
apiKey: CONFIG['FIREBASE_API_KEY'],
authDomain: CONFIG['FIREBASE_AUTH_DOMAIN'],
databaseURL: CONFIG['FIREBASE_DATABASE_URL'],
storageBucket: CONFIG['FIREBASE_STORAGE_BUCKET']
}
const fbApp = initializeApp(FIREBASE_CONFIG)
And later fetching data
export default function Leads() {
...
useEffect(() => {
const database = getDatabase(fbApp)
const ads = ref(database, 'ad_results')
get(ads).then((snap) => {
const results = snap.val()
...
I have tried searching similar issues but to no avail, any help would be appreciated.
I had the same issue with my Cloud Functions, which was very confusing. After some hours of debugging, I found out that the .get() method of the Realtime Database was causing this problem. My current workaround is to use instead .once('value').
So I changed my code from:
await database.ref(`foo/bar`).get();
to
await database.ref(`foo/bar`).once('value');
I am using firebase nodejs SDK, also facing the same error: "Error: Error: Client is offline." occasionally.
I have tried the above solution posted by Nils Reichardt. It works for me.
Thanks Nils!

Firebase & React js - Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app)

First of all, I have gone through my code and don't see anywhere where I might be initialising app more than once (unless I'm missing something).
I know this question has been asked and answered before but I'm not sure how to apply the solution to my own code as I'm just getting started with Firebase.
The error I'm getting is: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).
Here is my config component:
export const DB_CONFIG = {
apiKey: "AIzaSyDj_UQoRkOWehv-Ox2IAphOQPqciE6jL6I",
authDomain: "react-notes-38f8a.firebaseapp.com",
databaseURL: "https://react-notes-38f8a.firebaseio.com",
projectId: "react-notes-38f8a",
storageBucket: "react-notes-38f8a.appspot.com",
messagingSenderId: "1063805843776"
};
Here is App.js
constructor(props){
super(props);
this.app = firebase.initializeApp(DB_CONFIG);
this.database = this.app.database().ref.child('notes')
this.state = {
notes: [
],
}
}
componentWillMount(){
const previousNotes = this.state.notes;
this.database.on('child_added', snap => {
previousNotes.push({
id: snap.key,
noteContent: snap.val().noteContent
})
})
this.setState({
notes: previousNotes
})
}
Pretty Simple to solve out
Initialize Firebase in Conditional Block.
if(!firebase.apps.length)
firebase.initializeApp(DB_CONFIG);
Analysis: If we won't execute 'Initializing Firebase' inside the conditional block it simply getting confused by re-initialization so far.
Additional Note: This problem is not related to the config component, and we should try not to disclose firebase config credentials for security purposes.
If under this condition your app is defined, your problem will be solved.
if (!firebase.apps.length) {
firebase.initializeApp(DB_CONFIG);
}
This error occurs when you trying to initialize firebase again and again. It should be initialized only once to avoid Firebase app named ‘[DEFAULT]’ already exists and to achieve this you will have to change your initialization style.
You could do this with an if(!firebase.apps.length) { firebase.initializeApp(DB_CONFIG) }; as suggested above by #sdkcy or, for extra security you can also include a try / catch statement like:
if (!firebase.apps.length) {
try {
firebase.initializeApp(DB_CONFIG)
} catch (err) {
console.error(‘Firebase initialization error raised’, err.stack)
}
}
Using a try / catch statement your app should continue to function without breaking, regardless of whether the error was captured. So you can also try this code without the if statement wrapping it if you want to try to figure out why your constructor is being called twice.
Good luck!
This can happen when you use React and put the initializeApp in the Constructor.
It's better to put the this.app = firebase.initializeApp(DB_CONFIG); call in componentDidMount;

firebase.storage() takes either no argument or a Firebase App instance

Actually, the title is more or less the whole explanation of the problem.
I am trying to use Firebase inside my React app, which also uses NextJS and the problem is that I cannot get storage to work.
import firebase from 'firebase'
import uuid from 'uuid/v4'
// Init
try {
firebase.initializeApp({
apiKey: 'apiKey',
authDomain: 'authDomain',
databaseURL: 'dbUrl',
projectId: 'projID',
storageBucket: 'storageBucket',
messagingSenderId: 'id'
})
} catch (err) {
if (!/already exists/.test(err.message)) {
console.error('Firebase initialization error', err.stack)
}
}
console.log(firebase.app().name) // <- name
// References
const database = firebase.database()
const storage = firebase.storage().ref() // <- the problem
const documentImageStorage = storage.child('images/')
const documentsRef = database.ref('/documents/')
const documentsRequestsRef = database.ref('/requests/')
So, as I run the code I can confirm that the app works as the database works properly and the name ([default]) is returned correctly, but the line in which the storage reference is defined returns an error:
Firebase: firebase.storage() takes either no argument or a Firebase App instance. (app/invalid-app-argument).
Any ideas why this might happen? How can I solve it?
(Firebase Storage JS dev)
I was able to reproduce your error in Next.js. I'm not super familiar with it, but I understand Next.js does React-y server-side rendering, so the code you write for your page will generally be executed in the node server.
Unfortunately, Storage isn't supported in node right now, which includes server-side rendering contexts (feel free to leave a comment in the Github issue about your use case).
It should work in normal React apps (i.e. client-side code) though.
EDIT: found a (barely) workaround
The code appears to not crash in Next.js if you add an import at the top of the file:
import firebase from 'firebase'
import _s from 'firebase/storage'
import uuid from 'uuid/v4'
...
Regardless, the Storage library still isn't supported in node. Most anything interesting (uploading objects, getting object metadata) won't work, so unless all you wanted to do was call storage.toString() somewhere this probably doesn't solve your problem.
Firebase docs states that you save storage service reference to variable, then save storage reference to different variable.
https://firebase.google.com/docs/storage/web/create-reference
So I would do this like so:
const storage = firebase.storage();
const storageRef = storage.ref();
You can also put path to your storage folder to get reference for it, like this:
const documentImageStorage = storage.ref('/images/');
Ok, so I figured out how to make it work!
export const storage = process.browser ? firebase.storage().ref() : undefined
This way, storage part, which is unavailable on the backend isn't loaded, but on the frontend it is and everything works perfectly!
Thanks for both answers!

Categories

Resources