Documentation says: "The tokens are automatically refreshed by the library when necessary.". I call
AWSMobileClient.getInstance().getTokens().getAccessToken().getTokenString();
everytime before calling the API with AccessToken.
Here is what my awsconfiguration file looks like
`{
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "ap-xxxxx-1:2xxxxxx-xxxx-xxxx-xxxx-7xxxxxxxxxx",
"Region": "ap-xxxxx-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "ap-xxxxx-1_xxxxxxxxx",
"AppClientId": "xxxxxxxxxxxxxxxxxxxxx",
"Region": "ap-xxxxx-1"
}
}
After an hour, API returns 401(Authentication Error).
And AWSMobileClient.getInstance().getTokens().getAccessToken().getTokenString(); returns an error
AWSMobileClient: Tokens are invalid, please sign-in again.
java.lang.Exception: No cached session.
Am I doing something wrong?
PS: I have not used Amplify CLI.
So the problem was I was calling the getTokens() method from the main thread and it returned the tokens without refreshing. Then I moved the getTokens call inside the AWSMobileClient.getInstance().initialize(..) call and I got refreshed tokens whenever required.
Related
I am working on creating an android application for the java spring Webflux API client.
I want to use retrofit, OkHttps, and coroutines flow android.
A sample response looks like this
{
"status": "ACCEPTED",
"isFinish": false,
"metaInfo": {
"requestId": "0e442156-9211-4b21-aeae-a50ec4ac1715"
}
}
{
"status": "PROCESS",
"isFinish": false,
"metaInfo": {
"requestId": "0e442156-9211-4b21-aeae-a50ec4ac1715"
}
}
{
"status": "PROCESS",
"isFinish": false,
"metaInfo": {
"requestId": "0e442156-9211-4b21-aeae-a50ec4ac1715"
}
}
{
"status": "SUCCESS",
"isFinish": true,
"metaInfo": {
"requestId": "0e442156-9211-4b21-aeae-a50ec4ac1715"
}
}
Each of these responses comes after an unavoidable time delay and I need to be able to receive each response in time.
in a traditional poll, I can get it after the last response.
Any suggestions are important to me. Thank you
I have followed the tutorial:
https://aws-amplify.github.io/docs/android/start?ref=amplify-android-btn
To integrate AWS S3 with my android application.
I'm able to download a file, and everything works fine.
I've notice that when i create a enviroment, it creates a new bucket, i don't want to create a new bucket, i want to use an existing one.
I've tried to change the bucket in the awsconfiguration.json. But it does not work.
"S3TransferUtility": {
"Default": {
"Bucket": "somebucket",
"Region": "us-east-1"
}
}
AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: <ID>)
I don't want to create a new bucket, i want to be able to access crated buckets that share objects across other apps.
I solved. For anyone who is interested in.
For using an existing bucket, without creating a environment with amplify. The only thing i done was to add manually the file awsconfiguration.json inside the raw folder. I do not use amplify.
So, my awsconfiguration.json looks like:
{
"Version": "1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "cognito-pool-id",
"Region": "region"
}
}
},
"S3TransferUtility": {
"Default": {
"Bucket": "somebucket",
"Region": "region"
}
}
}
And to download objects from S3 i make my TransferUtility like this:
val transferUtility = TransferUtility.builder()
.context(context)
.awsConfiguration(AWSMobileClient.getInstance().configuration)
.s3Client(getAmazonS3Client())
.build()
private fun getAmazonS3Client(): AmazonS3Client{
if (amazonS3Client == null) {
amazonS3Client = AmazonS3Client(
CognitoCachingCredentialsProvider(
context,
BuildConfig.S3_POOL_ID,
Regions.US_EAST_2
),
Region.getRegion(Regions.US_EAST_2)
)
}
return amazonS3Client!!
}
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.
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"
}
}
}
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.
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.
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)
I am a newbie using AWS sdk for video transfer.But i am getting the error "Failed to read S3TransferUtility please check your setup or awsconfiguration.json file". Here is my code.
In my manifest file i have
<service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService" android:enabled="true" />
In my oncreate i am doing this.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upload_post);
AWSMobileClient.getInstance().initialize(this).execute();
transferUtility =
TransferUtility.builder()
.context(this)
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.s3Client(new AmazonS3Client(AWSMobileClient.getInstance().getCredentialsProvider()))
.build();
}
The exception comes at .build. I debugged the code and it picks up the config file located at in folder perfectly cause i can see the data in debug but i think the transferutility.TransferService is not running. Can someone please help. Thanx
For some reason the auto generated "awsconfiguration" file doesn't include the most important section called "S3TransferUtility". So you have to add it manually.
Your "awsconfiguration.json" file should look something like this:
{
"UserAgent": "MobileHub/1.0",
"Version": "1.0",
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "us-east-1:<RANDOM-GUID>",
"Region": "us-east-1"
}
}
},
"IdentityManager": {
"Default": {}
},
"PinpointAnalytics": {
"Default": {
"AppId": "<UNIQUE ID>",
"Region": "us-east-1"
}
},
"PinpointTargeting": {
"Default": {
"Region": "us-east-1"
}
},
"S3TransferUtility": {
"Default": {
"Bucket": "<YOUR BUCKET NAME>",
"Region": "us-east-1"
}
}
}
In my awsconfiguration.json i add below lines then it's started working
"S3TransferUtility": {
"Default": {
"Bucket": "<YOUR BUCKET NAME>",
"Region": "us-east-1"
}
}
Add awsconfiguration.json on your project and change pool id and region attributes. You can read more about it here.
I'm facing an issue with an android app while trying to retrieve some Api data using RxJava2 And Retrofit2 (in Kotlin). Once I execute the call, the screen turns black and the application just doesn't respond anymore, without any log messages.
The call URL I'm using is the following:
api/apartments?projection={"id":1,"address":1}
The Service interface for this call is this one:
#GET("api/apartments?projection={\"id\":1,\"address\":1}")
fun getAllApartments(#Header(AUTHORIZATION) auth: String): Single<List<APTLIST>>
This is the way I execute the call:
override fun getAllApartments(): Single<List<APTLIST>> = retrofit.create(ApartmentsService::class.java).getAllApartments("$BEARER$token")
And this is how I call the function:
getAllApartmentsUseCase.getAllApartments()
.subscribe(
{
apartments.clear()
apartments.addAll(it)
view.showApartments(apartments)
},
{ println(it.message) }
)
This call works on Postman and the result is the following:
[
{
"_id": "591ecaca861a528a5b4c3d90",
"id": "ROC 03"
},
{
"_id": "591a0fb2861a528a5b4c3d60"
},
{
"_id": "58be94d484c4b0a468fb93e0",
"id": "CAN 2.3",
"address": "Els Refugis"
}
]
I guess you are making web call in main thread. It is strange, that you just get something like ANR and not android.os.NetworkOnMainThreadException.
getAllApartmentsUseCase
.getAllApartments()
.subscribeOn(Schedulers.io()) //scheduler in which observable will execute
.observeOn(AndroidSchedulers.mainThread()) //scheduler in which subscriber's methods will be called
.subscribe(/*subscriber*/)
https://medium.com/upday-devs/rxjava-subscribeon-vs-observeon-9af518ded53a