I am trying to build some Firebase Cloud Functions, and also use the npm package camelcase-keys to transform the keys of an API response.
But whenever use that imported package I get this error:
Error: Failed to load function definition from source: Failed to
generate manifest from function source: 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.
This error is strange to me because I am following the advice here and only calling admin.initializeApp()
once at my function entry point (index.ts
).
Here is what the file structure looks like, and a copy of the code I am using.
Instead of including all the code, I have only included the salient parts (imports, exports, and admin.initializeApp). Let me know if more code pasted here would be helpful:
functions/
├─ src/
│ ├─ index.ts
│ ├─ dataForSeo.ts
index.ts
import 'source-map-support/register';
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
export const sydneyFunctions = functions.region('australia-southeast1');
export const db = admin.firestore();
export {
dataForSeoSerpGoogleOrganicDailyEnqueue,
dataForSeoSerpGoogleOrganicTask,
dataForSeoSerpGoogleOrganicPostbackUrl,
dataForSeoOnPageStartCrawl,
dataForSeoOnPageEnqueuePingbackUrl,
dataForSeoOnPageGetResultTask,
} from './dataForSeo';
dataForSeo.ts
import camelcaseKeys from 'camelcase-keys';
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import axios from 'axios';
import { getFunctions } from 'firebase-admin/functions';
import { DataForSeoGoogleOrganicPostTask, Serp, SerpItem } from './types';
import { getSecretVersion } from './googleSecretManager';
import { db, sydneyFunctions } from './index';
// Example usage
const test = camelcaseKeys(
{ 'foo-bar': true, nested: { unicorn_rainbow: true } },
{ deep: true }
);
functions.logger.info(test);
...
// Other functions below here
UPDATE:
Instead of using the camelcase-keys
package I tried creating a recursive function using lodash
that does the same thing.
This works without error:
import { camelCase, isPlainObject } from 'lodash';
const camelizeKeys = <
T extends Record<string, unknown> | Record<string, unknown>[]
>(
obj: T
): T => {
if (Array.isArray(obj)) {
return <T>obj.map((v) => camelizeKeys(v));
} else if (isPlainObject(obj)) {
return <T>Object.keys(obj).reduce(
(result, key) => ({
...result,
[camelCase(key)]: camelizeKeys(<T>obj[key]),
}),
{}
);
}
return obj;
};
While this custom function is a work-around, I would still like to get the camelcase-keys
package working.
2
Answers
That is a truly a strange case. I cannot say why it is occurring but to prevent re-initializing the app try this:
Had the exact same problem, I was following the Flutter Codelabs tutorial to implement IAP purchase (they use the in_app_purchase flutter library) verification into Firebase using Cloud Functions.
I got it working by downgrading the version used for camelcase-keys.
On your package.json file set camelcase-keys to version 6.2.2.
call npm install and then you should be able to deploy to firebase again.