3

How can I initialize cloud functions and service account together. In my index.ts file I have already initialized functions using

admin.initializeApp(functions.config().firebase);

but now I want to create create custom token with firebase, so I created a service account and added the service-account.json in my functions folder and added

const serviceAccount = require("./service-account.json");
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://functionstest-54bd9 .firebaseio.com"
});

above initialize functions. but when I tried to deploy the function, i got this error in the console

Error: The default Firebase app already exists. This means you called initializeApp() more than once without providing an app name as the second argument. In most cases you only need to call initializeApp() once. But if you do want to initialize multiple apps, pass a second argument to initializeApp() to give each app a unique name.
    at FirebaseAppError.FirebaseError [as constructor] (/home/me/Documents/TfmFirebase/functions/node_modules/firebase-admin/lib/utils/error.js:39:28)
    at FirebaseAppError.PrefixedFirebaseError [as constructor] (/home/me/Documents/TfmFirebase/functions/node_modules/firebase-admin/lib/utils/error.js:85:28)

I have only one app and I have added only a service account. Do I have to create another app just to create the custom token only? How can I fix this?

Update1

This is how I am creating custom token,

//create user
let writeResult = await db.collection('users').add({
                    user: user,
                    password: password,
                    isBlocked: false,
                    joiningDate: Date.now(),
                    phoneVerified: false,
                    deleted: false,
                    contacts:{
                        phone: phone
                    }
                })

//create token
let tokenSnapShot = await admin.auth().createCustomToken(writeResult.id);
const userRef = db.collection('users').doc(writeResult.id);
let updateResult = await userRef.get();
t.update(userRef,{ "token": updateResult.data() });

Please correct me if I am doing it wrong

halfer
  • 19,824
  • 17
  • 99
  • 186
Sony
  • 7,136
  • 5
  • 45
  • 68
  • `admin.initializeApp(functions.config().firebase);` should allow you to create custom tokens. Why do you need to use the service account too? – Sidney Mar 06 '18 at 18:16
  • I am not using sign in methods provided by firebase, because my app requires some more fields while registering the user. so registering is done in a cloud function and I am using the document id to create custom token, so that i can access it in firebase security rules. Can i use the document id as auth id in firebase rules? – Sony Mar 06 '18 at 18:22
  • "*I am using the document id to create custom token*" I'm not sure how that works. Maybe you could post your function code? – Sidney Mar 06 '18 at 18:26
  • @Sidney i have updated my question – Sony Mar 06 '18 at 18:32
  • It looks like you're storing all of your user data in your database. Is there a reason you aren't using firebase auth for storing passwords and handling authentication? – Sidney Mar 06 '18 at 18:38
  • In sign in methods, there are only phone number sign in and email/password sign with other federated providers, I am requesting username, phone and gender on signup – Sony Mar 06 '18 at 18:46
  • Hey did you find a solution to this? I am running into the exact same issue. – Dan Jun 06 '18 at 06:41

1 Answers1

6

I just was working on the same subject. When you work on at your localhost. You will need extra security to access your database. So, you will need to admin service key while working at localhost, and you may emulate only HTTPS functions. While working at firebase hosting you do not need this account key. But works fine either. Then you need to remove at your above code either

1.admin.initializeApp(functions.config().firebase); 

or

const serviceAccount = require("./service-account.json");
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://functionstest-54bd9 .firebaseio.com"
});
Cappittall
  • 3,300
  • 3
  • 15
  • 23
  • I am not using local server, i am deploying functions to firebase and accessing from there. I tried with only `admin.initializeApp(functions.config().firebase);` that gave me error stating that it requires a private key – Sony Mar 06 '18 at 18:52
  • If you have deployed the service key to the firebase hosting then use second choice only and delete the first line. `admin.initializeApp(functions.config().firebase); ` – Cappittall Mar 06 '18 at 18:55
  • And consider the service-account.json is original file name that you downloaded from the link :https://console.firebase.google.com/u/0/project/_/settings/serviceaccounts/adminsdk and be sure the path. At your situation this file seams to be located under `/functions /` root. – Cappittall Mar 06 '18 at 19:00
  • sorry, i didn't get this `if you have...` i have to use the service account every time when i register a user – Sony Mar 06 '18 at 19:06
  • the `service-account.json` is located inside the functions folder – Sony Mar 06 '18 at 19:09
  • If you work on firebase hosting, you don't have to have a service account key. just `admin.initializeApp(functions.config().firebase); ` is enough. BTW, when I downloaded the service account key. the original key name is seems: [appname]-firebase-adminsdk-9fnzd-310260a0c4.json , I mean this key.json should be hard guessed name. – Cappittall Mar 06 '18 at 19:12
  • i am not using firebase hosting for now, only cloud functions, for serving data to my mobile app. and i have edited the downloaded json file name to service-account.json – Sony Mar 06 '18 at 19:15
  • You said above: `I am not using local server, i am deploying functions to firebase and accessing from there. ` That I mean. You don't need a service key file. – Cappittall Mar 06 '18 at 19:16
  • but when i tried to create custom token from cloud function it gives error, create custom requires private key, that is why i added service account – Sony Mar 06 '18 at 19:18