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

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.

Related

How to hide firebase-admin credentials in Next Js

So I am using firebase-admin in Next Js. I used environment variables but can't hide the firebase service account keys because they are not defined in server-side on Next JS. So i had to use NEXT_PUBLIC environment variables. And NEXT_PUBLIC environment variables can be accessed and viewed in client side.
This is my firebase-admin file
const firebase = require("firebase-admin");
const { fireStore, getFirestore } = require("firebase-admin/firestore");
import { adminConfig } from "./serviceAccountKey";
if (!firebase.apps.length) {
firebase.initializeApp({
credential: firebase.credential.cert(adminConfig),
});
}
export const db = getFirestore();
export default firebase;
And this is how my config object looks like.
export const adminConfig = {
type: process.env.NEXT_PUBLIC_FIREBASE_TYPE,
project_id: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
private_key_id: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY_ID,
private_key: process.env.NEXT_PUBLIC_FIREBASE_PRIVATE_KEY,
client_email: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_EMAIL,
client_id: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_ID,
auth_uri: process.env.NEXT_PUBLIC_FIREBASE_AUTH_URI,
token_uri: process.env.NEXT_PUBLIC_FIREBASE_TOKEN_URI,
auth_provider_x509_cert_url:
process.env.NEXT_PUBLIC_FIREBASE_AUTH_PROVIDER_CERT_URL,
client_x509_cert_url: process.env.NEXT_PUBLIC_FIREBASE_CLIENT_CERT_URL,
};
So How do i hide the config data. Or is it alright even if it is public?
I managed to do this in NextJS some time back (hopefully it's still relevant) - try this:
Store your secrets as environment variables in a .env file.
In your next.config.js load the environment variables in publicRuntimeConfig
publicRuntimeConfig: {
PRIVATE_KEY: process.env.FIREBASE_PRIVATE_KEY_ID,
PRIVATE_KEY_ID: process.env.FIREBASE_PRIVATE_KEY
}
Then in your client side React:
import getConfig from 'next/config';
const {publicRuntimeConfig} = getConfig();
const private_key = publicRuntimeConfig.PRIVATE_KEY
const private_key_id = publicRuntimeConfig.PRIVATE_KEY_ID
EDIT: Actually, now that I think about it, I used this method for things that didnt require absolute security like API_URIs.
Secrets stored/accessed like this will still be exposed to inspection in the browser.
For anything that requires securely storing secrets, definitely perform them on server-side.

How to call a Cloud Function for Firebase in Vue3

I'm following the Net Ninja's tutorial about firebase cloud functions and I can't figure out how to call a function from a vue component. (he doesn't use vue in the tutorial).
So I have this vue3 app with firebase functions installed in it. How do I import the functions into a component? I can't find the answer anywhere. I'm still learning to code and I still don't understand very well how to import the packages needed.
I have a index.js file in the functions folder with a few functions inside.
I now want to call one of them ( a .onCall function) when clicking a button in a component.
I understand I need to import something in that component but I can't figure out what!
Your Vue.js app and your Cloud Functions for Firebase are totally different components of your whole application.
The Vue.js app is a front-end component (even if it is hosted in a cloud service like Firebase Hosting).
The Cloud Functions are serveless back-end components, hosted in the Firebase (Google Cloud) infrastructure and reacting to events.
To get these two components interacting with each other there are basically two possibilities:
For Callable Cloud Functions and HTTPS Cloud Functions, you will call them from your Vue.js app.
For background triggered Cloud Functions (e.g. triggered by a Firestore event like doc creation), the Vue.js front-end could generate the event (e.g. write to Firestore) and/or listen to the result of a Cloud Function execution (e.g. a Firestore doc is modified).
How do I import the functions into a component?
As explained above, you cannot integrate a Cloud Function code in your Vue.js code. In particular you cannot "import the functions into a component".
I now want to call one of them (a .onCall() function) when clicking a
button in a component.
If your Cloud Function is a Callable one, you can call it through the JS SDK as explained in the documentation.
UPDATE Following your comment:
As explained in the documentation, to call the Callable Function from your Vue.js app, you need to do as folloows (with the JS SDK v9):
Add Firebase to your Vue.js app. For example via a firebaseConfig.js file:
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getFunctions } from "firebase/functions";
const firebaseConfig = {
apiKey: "...",
// ....
};
const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
const functions = getFunctions(firebaseApp);
export { db, functions };
Then, in your component, you do
<script>
import { functions } from '../firebaseConfig';
import { httpsCallable } from 'firebase/functions';
// ...
methods: {
async callFunction() {
const addMessage = httpsCallable(functions, 'addMessage');
const result = await addMessage({ text: messageText })
const data = result.data;
//...
});
}
</script>

"Field Value is not a function" when I try to use the increment feature

I am trying to implement some simple thumbs up/thumbs down functionality in a react app using cloud firestore. The app lets users search for movies and give it a thumbs up or down, and then I want to increment the value in my frestore database. When I try to do this I'm given the error "FieldValue is not a function".
Here is my code in the component:
import {db}from './firebase'
const firebase = require("firebase/firestore");
const movieDocRef = db.collection("ratings").doc(title);
const increment = firebase.FieldValue.increment(1);
movieDocRef.update({thumbsUP: increment})
And here is my firebase config file
const firebase = require("firebase");
// Required for side-effects
require("firebase/firestore");
const config = {
//my config data all should fine
};
export const fire = firebase.initializeApp(config);
export const db = fire.firestore();
Would appreciate any help you can give. I've looked at a few similar topics and nothing seems to have resolved this
Since you are using react, I suggest reviewing the documentation for getting started with Firebase using module bundlers. Your imports should look more like this when using version 8.0.0 or later of the Firebase SDKs:
import firebase from "firebase/app";
import "firebase/firestore"
const movieDocRef = firebase.firestore().collection("ratings").doc(title);
movieDocRef.update({ thumbsUP: firebase.firestore.FieldValue.increment(1) })

Possible Unhandled Promise Rejection (id: 20): TypeError: _util.base64.tI is not a function. React Native

I am building an app using react native, I use firebase as my database. Everything was working fine. I started running the app on my device through Xcode. It worked but now I get this warning on my device and simulator which prevents me from getting data from firebase database. the warning is
"Possible Unhandled Promise Rejection (id: 20):
TypeError: _util.base64.tI is not a function. (In '_util.base64.tI(t, !1)', '_util.base64.tI' is undefined)"
I don't know where did this (_util.base64) come from. I guess the problem has to do with this code part (the promise) as when I remove this part it works fine but unable to get data without it. can anyone help?
useEffect(() => {
db.collection("Appointments")
.orderBy("Timing", "desc")
.limit(2)
.get()
.then((querySnapshot) => {
const list = [];
querySnapshot.forEach((doc) => {
const { Speciality, Date, TimeSlot } = doc.data();
list.push({
id: doc.id,
Speciality,
Date,
TimeSlot,
});
});
setAppointments(list);
})
.catch((error) => {
alert(error.message);
console.log(error);
});
}, []);
This is the warning that shows up
Those are my dependencies
What I did to solve it was:
run expo install firebase
Create a config.js file where I put my Firebase credentials:
import * as firebase from 'firebase';
// Initialize Firebase
var firebaseConfig = {
//Your Firebase credentials
};
var app = firebase.initializeApp(firebaseConfig);
export const db = app;
And import that file wherever I need it
import { db } from '../config';
//Here's where I call firestore (You can also do this in the config file)
import 'firebase/firestore';
db.firestore().
collection('your_collection').get().then(
//The stuff you want to do
);
At least, now it works for me.
In this link you can see the oficial expo with firebase documentation

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

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

Categories

Resources