I’m trying to implement a role-based authentication using Firebase auth and Firebase functions. Right now I have a registration form that is working as supposed and now I’m trying to add a form that you submit an email that calls the Firebase function that will attach a custom claim to a user. I already added my function to Firebase via the terminal and I’m calling functions on my project but whenever I submit the form with the email I get a httpsCallable is not a function
error.
Here are my files:
index.js inside functions folder
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); exports.addAdminRole = functions.https.onCall((data, context) => { //get user and add custom claim (admin) return admin .auth() .getUserByEmail(data.email) .then(user => { return admin.auth().setCustomUserClaims(user.uid, { admin: true }); }) .then(() => { return { message: `Success! ${data.email} has been made admin` }; }) .catch(err => { return err; }); });
My firebaseInit.js config file where I call everything firebase related
import firebase from "firebase/app"; import "firebase/firestore"; import "@firebase/functions"; import firebaseConfig from "./firebaseConfig"; const firebaseApp = firebase.initializeApp(firebaseConfig); export const fc = firebase.functions(); export const db = firebase.firestore(); export const fv = firebase.firestore.FieldValue; export default firebaseApp.firestore();
And my Vue component where the form is
<template> <div class="home"> <h3>Welcome to Site</h3> <h3>Add user to admin</h3> <div class="row"> <form @submit.prevent="addAdmin()" class="col s12"> <div class="row"> <div class="input-field col s12"> <input id="email" type="email" class="validate" v-model="email" /> <label for="email">Email</label> </div> </div> <button type="submit" class="btn">Submit</button> <router-link to="/members" class="btn grey">Cancel</router-link> </form> </div> </div> </template> <script> import firebase from "firebase/app"; import fc from "../data/firebaseInit"; export default { name: "home", data() { return { email: "" }; }, methods: { addAdmin() { const addAdminRole = fc.httpsCallable("addAdminRole"); addAdminRole(this.email).then(result => { console.log(result); }); } } }; </script>
Can someone shed a light on why I’m getting this error? Am I forgetting to import something firebase related?
Advertisement
Answer
Your problem comes from the fact that by doing
export const fc = firebase.functions(); export const db = firebase.firestore(); export const fv = firebase.firestore.FieldValue; export default firebaseApp.firestore();
in your firebaseInit.js
file, you aren’t exporting fc
(nor fv
by the way)
The following should work
import firebase from "firebase/app"; import "firebase/firestore"; import "firebase/functions"; // <-- Note that the @ was removed import firebaseConfig from "./firebaseConfig"; const firebaseApp = firebase.initializeApp(firebaseConfig); const fc = firebase.functions(); const db = firebase.firestore(); const fv = firebase.firestore.FieldValue; export { fc, db, fv };
Then, in your component you do:
import {fc, db, fv} from "../data/firebaseInit"; //....
Or the following it you only need fc
and db
, for example:
import {fc, db} from "../data/firebaseInit"; //....