9

I want to have different configuration for debug and release builds. All the configuration is stored inside awsconfiguration.json, for example I have two different config files how can I set which file should be used.

When using AWSMobileClient.getInstance() it gets default configuration from file awsconfiguration.json

Configuration file example:

{
  "Version": "1.0",
  "CredentialsProvider": {
    "CognitoIdentity": {
      "Default": {
        "PoolId": "DIFFERENT_VALUES",
        "Region": "DIFFERENT_VALUES"
      }
    }
  },
  "IdentityManager": {
    "Default": {}
  },
  "CognitoUserPool": {
    "Default": {
      "AppClientSecret": "DIFFERENT_VALUES",
      "AppClientId": "DIFFERENT_VALUES",
      "PoolId": "DIFFERENT_VALUES",
      "Region": "DIFFERENT_VALUES"
    }
  }
}

Update There is option to use different awsconfiguration.json by puting different files in main\res\raw and release\res\raw, for example by following this answer and it works. But I'm wondering whether there is an option to do it programmatically.

Roman Nazarevych
  • 7,513
  • 4
  • 62
  • 67

4 Answers4

10

This can also be acheived by setting the configuration value in AWSConfiguration and then initializing the AWSMobileClient.

    AWSConfiguration awsConfiguration = new AWSConfiguration(context);
    awsConfiguration.setConfiguration("Stage"); // BuildConfig can be used here.

    AWSMobileClient.getInstance().initialize(context, awsConfiguration,  new Callback<UserStateDetails>() {

        @Override
        public void onResult(UserStateDetails userStateDetails) {
        }

        @Override
        public void onError(Exception e) {
        }
    });

And the awsconfiguration.json file can be updated as below

{
 "Version": "1.0",
 "CredentialsProvider": {
    "CognitoIdentity": {
        "Default": {
            "PoolId": "DIFFERENT_VALUES",
            "Region": "DIFFERENT_VALUES"
        },
        "Stage": {
            "PoolId": "STAGE_VALUES",
            "Region": "STAGE_VALUES"
        }
    }
 },
 "IdentityManager": {
    "Default": {},
    "Stage": {}
 },
 "CognitoUserPool": {
    "Default": {
        "AppClientSecret": "DIFFERENT_VALUES",
        "AppClientId": "DIFFERENT_VALUES",
        "PoolId": "DIFFERENT_VALUES",
        "Region": "DIFFERENT_VALUES"
    },
    "Stage": {
        "AppClientSecret": "STAGE_VALUES",
        "AppClientId": "STAGE_VALUES",
        "PoolId": "STAGE_VALUES",
        "Region": "STAGE_VALUES"
    }
 }
}
Abhishek Anand
  • 293
  • 5
  • 11
  • how to generate awsconfiguration.json in android studio? – Bhavin Patel Jul 31 '21 at 07:29
  • 1
    Amplify.Auth continues using Default even after doing this. – CamHart Aug 23 '21 at 21:40
  • Do you have any idea how we can use separate CognitoUserPools from the AmplifyConfiguration.json file apart from the normal Default() one? I can't get it to change from default to use another such as Prod etc... (iOS App) – GameDev Mar 31 '22 at 14:16
8

I've been trying to achieve something similar; selecting an AWS configuration at runtime based on a selected profile. I got it partially working by hacking the AWS SDK but then stumbled across release notes for AWS SDK version 2.11.0. Quoting:

Added the option of passing the configuration as an in-memory object (i.e. [String: Any]/NSDictionary) instead of the default awsconfiguration.json through the new API

I've also found it documented(!) in the amplify getting started guide here.

So since 9th September 2019 it IS possible to select an AWS configuration at runtime.


Edit: Just noticed that this question is for Android rather than iOS. I'm not an Android developer but a quick searched revealed something similar in AWS Android SDK release 2.13.6 (7th June 2019). Quoting the release notes:

Add AWSConfiguration(JSONObject) constructor to construct a AWSConfiguration object from the configuration passed via a JSONObject

... which looks promising.

Nick Ager
  • 1,227
  • 14
  • 15
0

This can be done with source sets; eg. directories main & debug or directories debug & release, where res/raw or assets are not being processed by AAPT2. Adding credentials alike that is only suggested for internal use, because they can be easily extracted from the package.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
  • Thanks! That works, but I want to change it dynamically, for example, programmatically if there is such option. – Roman Nazarevych Jun 26 '19 at 14:59
  • Gradle configurations are fully script-able, so what's the problem? Adding credentials into the source code is a certain attack vector and therefore absolutely not suggested, no matter how often people may up-vote these "simple but Swiss cheese" answers. – Martin Zeitler Aug 27 '20 at 16:16
-1

Abhishek's answer is my favorite of these. But if you're using Amplify (as I am), while it's possible to put multiple configurations into a single file, I've not found a way of selecting between them.

So, although it's not an exact answer to the question, in Amplify you can select between multiple, self-contained configuration files like this:

When you set up Amplify:

Amplify.addPlugin(AWSCognitoAuthPlugin())
// and whatever other plugins you'll need...
Amplify.configure(AmplifyConfiguration.fromConfigFile(applicationContext, getConfigResourceId(applicationContext)), applicationContext)

And also add:

private fun getConfigResourceId(context: Context): Int = context.resources.getIdentifier("YourConfigFileName", "raw", context.packageName)
Dharman
  • 30,962
  • 25
  • 85
  • 135
Jules May
  • 753
  • 2
  • 10
  • 18
  • how to generate awsconfiguration.json in android studio? – Bhavin Patel Jul 31 '21 at 07:29
  • @bdevloper You don't generate awsConfigurations in Android Studio. You generate them in Amplify, and then save them in the res directory, where Android Studio can find them. – Jules May Aug 06 '21 at 11:55