Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit d0f3f3d

Browse files
Merge remote-tracking branch 'origin/master'
2 parents 9fa8c99 + d6083b5 commit d0f3f3d

File tree

3 files changed

+199
-12
lines changed

3 files changed

+199
-12
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Open your Firebase project at the Google console and click 'Add app' to add an i
3737

3838
* Android: `google-services.json` which you'll add to your NativeScript project at `app/App_Resources/Android/google-services.json`
3939

40+
Note: for using separate versions of these files for dev/prod environments see [this section](#separation-of-environments)
41+
4042
## Installation
4143
If you rather watch a (slightly outdated) video explaining the steps then check out this step-by-step guide - you'll also learn how to
4244
add iOS and Android support to the Firebase console and how to integrate anonymous authentication:
@@ -268,3 +270,28 @@ android {
268270
```
269271

270272
Where `"15.0.0"` is best set to the same value as the `googlePlayServicesVersion` value in [this file](https://github.com/EddyVerbruggen/nativescript-plugin-firebase/blob/48a99ccd2a0f590c37080b1a252173ea9b996e9f/publish/scripts/installer.js#L540).
273+
274+
## Separation of Environments
275+
276+
It is possible to use different development and production environments by using multiple `GoogleService-Info.plist` and `google-services.json` files.
277+
278+
### Setup
279+
1. Create two separate Firebase projects (e.g. `myproject` and `myproject-dev`) and configure them with the same package name
280+
2. Download the `plist` and `json` files for both projects and put them in the relevant directories with either `.dev` or `.prod` appended to the file names, so you have the following files in place:
281+
282+
* iOS
283+
* `app/App_Resources/iOS/GoogleService-Info.plist.dev`
284+
* `app/App_Resources/iOS/GoogleService-Info.plist.prod`
285+
* Android
286+
* `app/App_Resources/Android/google-services.json.dev`
287+
* `app/App_Resources/Android/google-services.json.prod`
288+
289+
Note: if you currently have the `storageBucket` property in the `firebase.init()` then remove it (not mandatory anymore as of version `6.5.0` of this plugin), so it will be taken automatically from the relevant google services `plist` and `json` files.
290+
291+
### Build
292+
The after-prepare hook of this plugin will now choose either the `dev` or the `prod` version of your google services `plist` and `json` files depending on how you run your build:
293+
294+
* `prod` will be selected if you run with either the `--release`, `--env.prod` or `--env.production` flags
295+
* `dev` will be selected if you do not run with the above flags
296+
297+
Note: if you do not have both `dev` and `prod` files in place, the regular `GoogleService-Info.plist` and `google-services.json` files will be used.

src/firebase.ios.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,7 @@ firebase.firestore.add = (collectionPath: string, document: any): Promise<firest
19081908
reject("Make sure 'Firebase/Firestore' is in the plugin's Podfile");
19091909
return;
19101910
}
1911-
1911+
fixSpecialFields(document);
19121912
const defaultFirestore = FIRFirestore.firestore();
19131913
const fIRDocumentReference = defaultFirestore
19141914
.collectionWithPath(collectionPath)

src/scripts/postinstall.js

Lines changed: 171 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3417,22 +3417,68 @@ apply plugin: "com.google.gms.google-services"
34173417

34183418
/**
34193419
* Installs an after-prepare build hook to copy the app/App_Resources/Android/google-services.json to platform/android on build.
3420+
* Installs before-checkForChange build hook to detect changes in environment and copy GoogleServices.plist on build
34203421
*/
34213422
function writeGoogleServiceCopyHook() {
3422-
console.log("Install google-service.json copy hook.");
3423+
3424+
/*
3425+
Install after-prepare hook
3426+
*/
3427+
3428+
console.log("Install google-service.json after-prepare copy hook.");
34233429
try {
3424-
var scriptContent =
3430+
var afterPrepareScriptContent =
34253431
`
34263432
var path = require("path");
34273433
var fs = require("fs");
34283434
34293435
module.exports = function($logger, $projectData, hookArgs) {
34303436
3431-
return new Promise(function(resolve, reject) {
3437+
return new Promise(function(resolve, reject) {
3438+
3439+
/* Decide whether to prepare for dev or prod environment */
3440+
3441+
var isReleaseBuild = (hookArgs.appFilesUpdaterOptions && hookArgs.appFilesUpdaterOptions.release) ? true : false;
3442+
var validProdEnvs = ['prod','production'];
3443+
var isProdEnv = false; // building with --env.prod or --env.production flag
3444+
3445+
if (hookArgs.platformSpecificData.env) {
3446+
Object.keys(hookArgs.platformSpecificData.env).forEach((key) => {
3447+
if (validProdEnvs.indexOf(key)>-1) { isProdEnv=true; }
3448+
});
3449+
}
3450+
3451+
var buildType = isReleaseBuild || isProdEnv ? 'production' : 'development';
3452+
3453+
/* Create info file in platforms dir so we can detect changes in environment and force prepare if needed */
3454+
3455+
var npfInfoPath = path.join($projectData.platformsDir, hookArgs.platform.toLowerCase(), ".pluginfirebaseinfo");
3456+
var npfInfo = {
3457+
buildType: buildType,
3458+
};
3459+
3460+
try { fs.writeFileSync(npfInfoPath, JSON.stringify(npfInfo)); }
3461+
catch (err) {
3462+
$logger.info('nativescript-plugin-firebase: unable to create '+npfInfoPath+', prepare will be forced next time!');
3463+
}
3464+
3465+
3466+
/* Handle preparing of Google Services files */
3467+
34323468
if (hookArgs.platform.toLowerCase() === 'android') {
3433-
var sourceGoogleJson = path.join($projectData.appResourcesDirectoryPath, "Android", "google-services.json");
34343469
var destinationGoogleJson = path.join($projectData.platformsDir, "android", "app", "google-services.json");
34353470
var destinationGoogleJsonAlt = path.join($projectData.platformsDir, "android", "google-services.json");
3471+
var sourceGoogleJson = path.join($projectData.appResourcesDirectoryPath, "Android", "google-services.json");
3472+
var sourceGoogleJsonProd = path.join($projectData.appResourcesDirectoryPath, "Android", "google-services.json.prod");
3473+
var sourceGoogleJsonDev = path.join($projectData.appResourcesDirectoryPath, "Android", "google-services.json.dev");
3474+
3475+
// ensure we have both dev/prod versions so we never overwrite singlular google-services.json
3476+
if (fs.existsSync(sourceGoogleJsonProd) && fs.existsSync(sourceGoogleJsonDev)) {
3477+
if (buildType==='production') { sourceGoogleJson = sourceGoogleJsonProd; } // use prod version
3478+
else { sourceGoogleJson = sourceGoogleJsonDev; } // use dev version
3479+
}
3480+
3481+
// copy correct version to destination
34363482
if (fs.existsSync(sourceGoogleJson) && fs.existsSync(path.dirname(destinationGoogleJson))) {
34373483
$logger.out("Copy " + sourceGoogleJson + " to " + destinationGoogleJson + ".");
34383484
fs.writeFileSync(destinationGoogleJson, fs.readFileSync(sourceGoogleJson));
@@ -3447,11 +3493,16 @@ module.exports = function($logger, $projectData, hookArgs) {
34473493
reject();
34483494
}
34493495
} else if (hookArgs.platform.toLowerCase() === 'ios') {
3450-
var sourceGooglePlist = path.join($projectData.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist");
3451-
if (!fs.existsSync(sourceGooglePlist)) {
3452-
$logger.warn(sourceGooglePlist + " does not exist. Please follow the installation instructions from the documentation");
3453-
return reject();
3454-
} else {
3496+
// we have copied our GoogleService-Info.plist during before-checkForChanges hook, here we delete it to avoid changes in git
3497+
var destinationGooglePlist = path.join($projectData.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist");
3498+
var sourceGooglePlistProd = path.join($projectData.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist.prod");
3499+
var sourceGooglePlistDev = path.join($projectData.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist.dev");
3500+
3501+
// if we have both dev/prod versions, let's remove GoogleService-Info.plist in destination dir
3502+
if (fs.existsSync(sourceGooglePlistProd) && fs.existsSync(sourceGooglePlistDev)) {
3503+
if (fs.existsSync(destinationGooglePlist)) { fs.unlinkSync(destinationGooglePlist); }
3504+
resolve();
3505+
} else { // single GoogleService-Info.plist modus
34553506
resolve();
34563507
}
34573508
} else {
@@ -3469,9 +3520,118 @@ module.exports = function($logger, $projectData, hookArgs) {
34693520
}
34703521
fs.mkdirSync(afterPrepareDirPath);
34713522
}
3472-
fs.writeFileSync(scriptPath, scriptContent);
3523+
fs.writeFileSync(scriptPath, afterPrepareScriptContent);
3524+
} catch(e) {
3525+
console.log("Failed to install google-service.json after-prepare copy hook.");
3526+
console.log(e);
3527+
}
3528+
3529+
/*
3530+
Install before-checkForChanges hook
3531+
*/
3532+
3533+
console.log("Install google-service.json before-checkForChanges copy hook.");
3534+
try {
3535+
var beforeCheckForChangesContent =
3536+
`
3537+
var path = require("path");
3538+
var fs = require("fs");
3539+
3540+
module.exports = function($logger, $projectData, hookArgs) {
3541+
return new Promise(function(resolve, reject) {
3542+
3543+
/* Decide whether to prepare for dev or prod environment */
3544+
3545+
var isReleaseBuild = hookArgs['checkForChangesOpts']['projectData']['$options']['argv']['release'] || false;
3546+
var validProdEnvs = ['prod','production'];
3547+
var isProdEnv = false; // building with --env.prod or --env.production flag
3548+
3549+
var env = hookArgs['checkForChangesOpts']['projectData']['$options']['argv']['env'];
3550+
if (env) {
3551+
Object.keys(env).forEach((key) => {
3552+
if (validProdEnvs.indexOf(key)>-1) { isProdEnv=true; }
3553+
});
3554+
}
3555+
3556+
var buildType = isReleaseBuild || isProdEnv ? 'production' : 'development';
3557+
3558+
/*
3559+
Detect if we have nativescript-plugin-firebase temp file created during after-prepare hook, so we know
3560+
for which environment {development|prod} the project was prepared. If needed, we delete the NS .nsprepareinfo
3561+
file so we force a new prepare
3562+
*/
3563+
var platform = hookArgs['checkForChangesOpts']['platform'].toLowerCase(); // ios | android
3564+
var platformsDir = hookArgs['checkForChangesOpts']['projectData']['platformsDir'];
3565+
var appResourcesDirectoryPath = hookArgs['checkForChangesOpts']['projectData']['appResourcesDirectoryPath'];
3566+
var forcePrepare = true; // whether to force NS to run prepare
3567+
var npfInfoPath = path.join(platformsDir, platform, ".pluginfirebaseinfo");
3568+
var nsPrepareInfoPath = path.join(platformsDir, platform, ".nsprepareinfo");
3569+
var copyPlistOpts = { platform, appResourcesDirectoryPath, buildType, $logger }
3570+
3571+
if (fs.existsSync(npfInfoPath)) {
3572+
var npfInfo = undefined;
3573+
try { npfInfo = JSON.parse(fs.readFileSync(npfInfoPath, 'utf8')); }
3574+
catch (e) { $logger.info('nativescript-plugin-firebase: error reading '+npfInfoPath); }
3575+
3576+
if (npfInfo && npfInfo.hasOwnProperty('buildType') && npfInfo.buildType===buildType) {
3577+
$logger.info('nativescript-plugin-firebase: building for same environment, not forcing prepare.');
3578+
forcePrepare=false;
3579+
}
3580+
} else { $logger.info('nativescript-plugin-firebase: '+npfInfoPath+' not found, forcing prepare!'); }
3581+
3582+
if (forcePrepare && fs.existsSync(nsPrepareInfoPath)) {
3583+
$logger.info('nativescript-plugin-firebase: running release build or change in environment detected, forcing prepare!');
3584+
3585+
if (fs.existsSync(npfInfoPath)) { fs.unlinkSync(npfInfoPath); }
3586+
fs.unlinkSync(nsPrepareInfoPath);
3587+
3588+
if (copyPlist(copyPlistOpts)) { resolve(); } else { reject(); }
3589+
} else { if (copyPlist(copyPlistOpts)) { resolve(); } else { reject(); } }
3590+
});
3591+
};
3592+
3593+
/*
3594+
Handle preparing of Google Services files for iOS
3595+
*/
3596+
var copyPlist = function(copyPlistOpts) {
3597+
if (copyPlistOpts.platform === 'android') { return true; }
3598+
else if (copyPlistOpts.platform === 'ios') {
3599+
var sourceGooglePlistProd = path.join(copyPlistOpts.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist.prod");
3600+
var sourceGooglePlistDev = path.join(copyPlistOpts.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist.dev");
3601+
var destinationGooglePlist = path.join(copyPlistOpts.appResourcesDirectoryPath, "iOS", "GoogleService-Info.plist");
3602+
3603+
// if we have both dev/prod versions, we copy (or overwrite) GoogleService-Info.plist in destination dir
3604+
if (fs.existsSync(sourceGooglePlistProd) && fs.existsSync(sourceGooglePlistDev)) {
3605+
if (copyPlistOpts.buildType==='production') { // use prod version
3606+
copyPlistOpts.$logger.out("nativescript-plugin-firebase: copy " + sourceGooglePlistProd + " to " + destinationGooglePlist + ".");
3607+
fs.writeFileSync(destinationGooglePlist, fs.readFileSync(sourceGooglePlistProd));
3608+
return true;
3609+
} else { // use dev version
3610+
copyPlistOpts.$logger.out("nativescript-plugin-firebase: copy " + sourceGooglePlistDev + " to " + destinationGooglePlist + ".");
3611+
fs.writeFileSync(destinationGooglePlist, fs.readFileSync(sourceGooglePlistDev));
3612+
return true;
3613+
}
3614+
} else if (!fs.existsSync(sourceGooglePlist)) { // single GoogleService-Info.plist modus but missing
3615+
copyPlistOpts.$logger.warn("nativescript-plugin-firebase: " + sourceGooglePlist + " does not exist. Please follow the installation instructions from the documentation");
3616+
return false;
3617+
} else {
3618+
return true; // single GoogleService-Info.plist modus
3619+
}
3620+
} else { return true; }
3621+
}
3622+
`;
3623+
var scriptPath = path.join(appRoot, "hooks", "before-checkForChanges", "firebase-copy-google-services.js");
3624+
var afterPrepareDirPath = path.dirname(scriptPath);
3625+
var hooksDirPath = path.dirname(afterPrepareDirPath);
3626+
if (!fs.existsSync(afterPrepareDirPath)) {
3627+
if (!fs.existsSync(hooksDirPath)) {
3628+
fs.mkdirSync(hooksDirPath);
3629+
}
3630+
fs.mkdirSync(afterPrepareDirPath);
3631+
}
3632+
fs.writeFileSync(scriptPath, beforeCheckForChangesContent);
34733633
} catch(e) {
3474-
console.log("Failed to install google-service.json copy hook.");
3634+
console.log("Failed to install google-service.json before-checkForChanges copy hook.");
34753635
console.log(e);
34763636
}
34773637
}

0 commit comments

Comments
 (0)