How to get push interactive notification with Urban Airship in Android? - android

I've integrated Urban Airship SDK to my application on device with Android 4.2 (Jelly Bean). I've received general push-notifications. It's Ok. But I want to get interactive push-notification with button with "Save" label.
My dependencies from build.gradle:
dependencies {
compile 'com.google.code.gson:gson:2.2.4'
compile 'com.google.android.gms:play-services:+'
compile project (':urbanairship-lib-6.1.1')
compile 'com.android.support:support-v4:22.2.0'
// Recommended for in-app messaging
compile 'com.android.support:cardview-v7:22.2.0'
// Recommended for location services
compile 'com.google.android.gms:play-services-location:7.5.0'
// Required for Android (GCM) push notifications
compile 'com.google.android.gms:play-services-gcm:7.5.0'
compile files('libs/commons-io-2.4.jar')
compile files('libs/FlurryAnalytics-4.1.0.jar')
compile files('libs/nineoldandroids-2.4.0.jar')
}
According to official documentation, I've added the following code in the onCreate() method in MyApplication class:
#Override
public void onCreate() {
AirshipConfigOptions options = new AirshipConfigOptions();
options.developmentAppKey = "sdgsdgsdhsdh";
options.developmentAppSecret = "sdhsdhsdhsdhsh";
options.productionAppKey = "Your Production App Key";
options.productionAppSecret = "Your Production App Secret";
options.inProduction = false;
options.gcmSender = "11111111";
UAirship.takeOff(this, options);
NotificationActionButton hiButtonAction = new NotificationActionButton.Builder("btnSave")
.setLabel(R.string.save)
.setPerformsInForeground(true)
.build();
// Define the group
NotificationActionButtonGroup buttonGroup = new NotificationActionButtonGroup.Builder()
.addNotificationActionButton(hiButtonAction)
.build();
// Add the custom group
UAirship.shared().getPushManager().addNotificationActionButtonGroup("save", buttonGroup);
UAirship.shared().getPushManager().setUserNotificationsEnabled(true);
UAirship.shared().getPushManager().setPushEnabled(true);
}
After that I've tried test push from my Urban Airship account:
EDIT:
I've used Urban Airship API v3. According to official documentation I've sent push with json:
{
"audience": {
"named_user": "2971"
},
"device_types":["android"],
"notification": {
"android": {
"alert": "Hello",
"extra": {
"EEID": "2971",
"DATE": "20150601"
},
"interactive": {
"type": "save"
}
}
}
}
But I've received general push-notification with "Hello" text and without any buttons.
What could be the problem and how to open some activity by click on the button in notification?
Thanks in advance.

The key "category" is not the correct on Android. Its actually looking for "com.urbanairship.interactive_type". However you should be either using the main composer or the push API directly.
curl -v -X POST -u <APP_KEY>:<MASTER_SECRET> -H "Content-type: application/json" -H "Accept: application/vnd.urbanairship+json; version=3;" --data '{
"audience":"ALL",
"device_types":["android"],
"notification": {
"android": {
"alert": "Hello",
"interactive": {
"type": "save"
}
}
}
}' https://go.urbanairship.com/api/push/
But with your apps credentials for <APP_KEY>:<MASTER_SECRET>
See http://docs.urbanairship.com/api/ua.html#interactive-api for more details.

Related

MSAL with EWS for Android gives Need admin approval

I try to change an authentication method from basic to oAuth for Android app. So I decided to use MSAL library, registered an app to Azure App registration, added Android to authentication platform config and added "EWS.AccessAsUser.All" permission in "Office 365 Exchange Online" group.
Here is how my config looks like:
{
"client_id" : "MY_CLIENT_ID_HETE",
"authorization_user_agent" : "DEFAULT",
"redirect_uri" : "msauth://com.testing.testauth/MY_KEY_HASH_HETE",
"authorities" : [
{
"type": "AAD",
"audience": {
"type": "AzureADandPersonalMicrosoftAccount",
"tenant_id": "common"
}
}
]
}
In android app for scopes I use [https://outlook.office365.com/EWS.AccessAsUser.All].
Here is the code how I use auth lib:
PublicClientApplication.createMultipleAccountPublicClientApplication(this,
R.raw.msal_config,
object : IMultipleAccountApplicationCreatedListener {
override fun onCreated(application: IMultipleAccountPublicClientApplication) {
}
override fun onError(exception: MsalException) {
}
})
}
After that when trying to log in, entering email and password I receive notification "Need admin approval" with message "AADSTS900941: This operation can only be performed as administrator".
Any ideas what am I doing wrong? Thanks in advance.

Firebase Cloud messaging doesn't work for Build variant on Android

I have 2 projects in Firebase: nl.companyname and nl.companyname.acc:
This is my build.gradle:
flavorDimensions "type"
productFlavors {
acceptance {
dimension="type"
applicationIdSuffix ".acc"
versionNameSuffix "-acc"
}
production {
dimension="type"
applicationIdSuffix ""
versionNameSuffix ""
}
}
The download google-services.json is in directory:
app/google-services.json
Android Studio is logged in to the Google account and synchronized:
The message shows up as successfully sent:
Problem description:
When sending a message on nl.companyname, it works.
When sending a message and targeting the device's Token ID, it works.
But the nl.companyname.acc doesn't work.
Steps tried:
I've deleted the .acc App in Firebase and re-added it (and downloaded the new json file).
Any help is greatly appreciated.
In the Firebase Document, it supports multiple flavor based project.
You can have multiple google-services.json files for different build
variants) by placing google-services.json files in dedicated
directories named for each variant under the app module root. For
example, if you have "development" and "release" build flavors, your
configuration could be organized like this:
app/
google-services.json
src/development/google-services.json
src/release/google-services.json
...
You can find full instruction at here.
Are you sure that your google-services.json are like this?
{
"project_info": {
...
},
"client": [
{
"client_info": {
...
"android_client_info": {
"package_name": "nl.companyname"
}
},
...
},
{
"client_info": {
...
"android_client_info": {
"package_name": "nl.companyname.acc"
}
},
...
}
],
...
}
On your app/gralde.build try something like this
buildTypes {
acceptance {
applicationIdSuffix '.acc'
...
}
release {
...
}
}
Remove google-services.json from build.gradle
Create Application class
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("0")
.build();
FirebaseApp.initializeApp(this, options);
}
}
Register this class in Manifest
<application
android:name=".extra.MyApplication"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:theme="#style/AppTheme">
On your Main Activity you need to call below method which generates FCM Token,(Which is similar like FirebaseInstanceIdService)
new GetFCMToken().execute();
private class GetFCMToken extends AsyncTask<String,Integer,String>{
#Override
protected String doInBackground(String... params) {
//you can update this id based on your flavour
String senderId = "1223";//put your FireBase project Sender Id
String sToken = "";
try {
// Check for current token
// Resets Instance ID and revokes all tokens.
FirebaseInstanceId.getInstance().deleteInstanceId();
// Clear current saved token
// Check for success of empty token
// Now manually call onTokenRefresh()
Log.d("TAG", "Getting new token");
sToken = FirebaseInstanceId.getInstance().getToken(senderId, "FCM");
Log.d("TAG", "s" + sToken);
} catch (IOException e) {
e.printStackTrace();
Log.e("e", "e", e);
}
return sToken;
}
#Override
protected void onPostExecute(String fcmToken) {
super.onPostExecute(fcmToken);
//Use this token to send notification
Log.e("FCM_TOKEN",fcmToken);
//Send Token server
}
}
You can find SenderId from firebase cosole -->Project Setting --> Cloud Messaging.
And Make sure you have added your package name in Fcm Console.
FirebaseMessegingReceiver.class work as it is.
Main benefit of this code is that,
No need to add google-services.json
Multiple firebase project work with single code.
No need to add FirebaseInstanceIdService in Manifest.

AWS DynamoDB access from Android, access denied to table

I'm trying to do CRUD operations on a NoSQL DynamoDB, I originally had not integrated a CognitoPool with my project on the AWS Mobile Hub but I have no done that and replaced my json file in the "raw" directory in my project. The DB is completely public both read and write but for some reason I keep getting this error:
com.amazonaws.AmazonServiceException: User: arn:aws:sts::1234567890:assumed-role/shoppinglist_unauth_MOBILEHUB_1234567890/CognitoIdentityCredentials is not authorized to perform: dynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:1234567890:table/ShoppingLists (Service: AmazonDynamoDB; Status Code: 400; Error Code: AccessDeniedException; Request ID: BQ0HAP7PUGO6AUC04LOHUND1V3VV4KQNSO5AEMVJF66Q9ASUAAJG)
I've changed all the identifying numbers to 1234567890 for security reasons.
This is my .json file:
{
"UserAgent": "MobileHub/1.0",
"Version": "1.0",
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "us-east-1******************,
"Region": "us-east-1"
}
}
},
"IdentityManager": {
"Default": {}
},
"CognitoUserPool": {
"Default": {
"PoolId": "us-east-1_*******",
"AppClientId": "5lg571jsd60ruvair8jiqpefbs",
"AppClientSecret": "bqn8edlp19gfgogfhf4j9qg1mq8u8ftpb328f652n0451gl2dnt",
"Region": "us-east-1"
}
},
"DynamoDBObjectMapper": {
"Default": {
"Region": "us-east-1"
}
},
"PinpointAnalytics": {
"Default": {
"AppId": "27e0f3ee2e63419c9dc8f18f23a294fe",
"Region": "us-east-1"
}
},
"PinpointTargeting": {
"Default": {
"Region": "us-east-1"
}
}
}
This is my onCreate() method in my main activity class
AWSMobileClient.getInstance().initialize(this, awsStartupResult ->
Log.d("YourMainActivity", "AWSMobileClient is instantiated and you are connected to AWS!"))
.execute();
// Instantiate a AmazonDynamoDBMapperClient
AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(AWSMobileClient.getInstance().getCredentialsProvider());
this.dynamoDBMapper = DynamoDBMapper.builder()
.dynamoDBClient(dynamoDBClient)
.awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
.build();
Runnable runnable = () -> {
dbClient = new AmazonDynamoDBClient(AWSMobileClient.getInstance().getCredentialsProvider());
// Create a table reference
dbTable = Table.loadTable(dbClient, "ShoppingLists");
Document memo = new Document();
memo.put("Apple", "apple");
dbTable.putItem(memo);
};
Thread myThread = new Thread(runnable);
myThread.start();
My build.gradle should hold the correct dependencies, those are here, granted it may be a bit of a mess:
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+#aar') { transitive = true }
implementation 'com.amazonaws:aws-android-sdk-core:2.6.18'
implementation 'com.amazonaws:aws-android-sdk-s3:2.6.18'
implementation 'com.amazonaws:aws-android-sdk-ddb:2.6.18'
implementation 'com.amazonaws:aws-android-sdk-ddb-mapper:2.6.18'
compile 'com.amazonaws:aws-android-sdk-core:2.6.18'
compile 'com.amazonaws:aws-android-sdk-ddb:2.6.18'
compile 'com.amazonaws:aws-android-sdk-ddb-document:2.4.4'
// Mobile Client for initializing the SDK
implementation ('com.amazonaws:aws-android-sdk-mobile-client:2.6.+#aar') { transitive = true }
// Cognito UserPools for SignIn
implementation 'com.android.support:support-v4:27.1.1'
implementation ('com.amazonaws:aws-android-sdk-auth-userpools:2.6.+#aar') { transitive = true }
// Sign in UI Library
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation ('com.amazonaws:aws-android-sdk-auth-ui:2.6.+#aar') { transitive = true }
As far as I can tell this should work fine, I was helped by another helpful person here to get to the point where it would connect to AWS which it did do at one point but I just can't seem to access the table.
I guess I have two questions, is it possible to do this without a Cognito pool at all and just have it completely unsecure? And if not, how do I get this to work with the Cognito Pool? Should the cognito pool have user names associated with it?
Let me take a crack at answering your questions
1) Can you do this without a Cognito Identity pool? The answer is Yes. This doesn't automatically mean that it is insecure - you can use AWS credentials that you setup for an IAM user. The best practice, however, is to use Cognito Identity pool, which will give you temporary AWS credentials that are valid for a short amount of time.
2) When you create a Cognito Identity pool, two roles (named auth and unauth) are automatically created. The "auth" role is for the cases where you have a signed in user ( for example, signed in using a social login like Facebook and federated to AWS through the Identity pool) and the "unauth" role is for a user who hasn't yet signed in. You can fine-tune the access privileges for these roles using IAM policies to best suit your application's needs.
See this page (https://docs.aws.amazon.com/aws-mobile/latest/developerguide/how-to-nosql-integrate-an-existing-table.html) for specific instructions on how to get this working.

Push notification to Android from Rails api using FCM is not sending the notification?

i am coding an Api Rest in rails 5, using gem 'fcm' to send notifications. I have already configure firebase in my android app and I can send notifications successfully from the Firebase console, but from my rails api i cannot receive the notificacion in my device, this is my code:
this is my rails controller:
class AccionesController < ApplicationController
def enviar
require 'fcm'
fcm = FCM.new("AAAAlBfTsV4:AheregoesmySERVEKEYsXXm-vQGfMjVuo8TpYrApHsnGU4ZasdfajsdfñalUtf26LeND4U4lXFZZplpzJjTWoiisWP-Esl5afCSTmiDI9y5gP6OObqY76NVcOn9ceaIUGMZ")
# fcm = FCM.new("my_server_key", timeout: 3)
registration_ids= [params[:devicetoken]] # an array of one or more client registration tokens
options = {data: {score: "mynewscore"},
notification: {
title: "Message Title",
body: "Hi, Worked perfectly",
icon: "myicon"}
,collapse_key: "testeando desde rails", priority: "high"}
response = fcm.send(registration_ids, options)
render json: response
end
def noti_params
params.permit(:devicetoken)
end
end
I execute from Postman this is the route that execute the controller:
http://localhost:3000/acciones/enviar?here goes the device token as parameter
And, here is the response:
{"body":"{\"multicast_id\":5276983113254623155,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1502991819420287%2293308c2293308c\"}]}","headers":{"content-type":["application/json;
charset=UTF-8"],"date":["Thu, 17 Aug 2017 17:43:39
GMT"],"expires":["Thu, 17 Aug 2017 17:43:39
GMT"],"cache-control":["private,
max-age=0"],"x-content-type-options":["nosniff"],"x-frame-options":["SAMEORIGIN"],"x-xss-protection":["1;
mode=block"],"server":["GSE"],"alt-svc":["quic=\":443\"; ma=2592000;
v=\"39,38,37,35\""],"accept-ranges":["none"],"vary":["Accept-Encoding"],"connection":["close"]},"status_code":200,"response":"success","canonical_ids":[],"not_registered_ids":[]}
the response shows success: 1 and status code: 200 but the notification never reaches the device,and the firebase console does not show the message.
Am I missing something?
please help?
or is there another way or ruby gem to send notification with a clear example?
any suggestions are welcome... thanks in advance
Instead of using fcm gem, you can also use RestClient gem. The usage for fcm notifications is as follow.One thing to note is if the payload is passing using ".to_json", the header content type also must be specified as json. Hope this help.
def self.send_noti(device_token)
options = data().merge ({"to": "#{device_token}"})
RestClient.post("https://fcm.googleapis.com/fcm/send", options.to_json, headers={'Content-Type' => 'application/json','Authorization' => "key=#{ENV['fcm_token']}"})
end
def self.data()
options = {
"notification": {
"body": "Your noti body",
"title": "Your noti title"
},
"data": {
"d1": "Your data" #can be any, d1, status or whatever
}
}
end
rest-client gem
fcm_client = FCM.new(your_firebase_key)
registration_ids= [user_device_token]
options = {
priority: 'high',
data: {
message: "Hai",
location: location
},
notification: {
body: "Hai",
location: "location",
sound: 'default'
}
}
fcm_client.send(registration_ids, options)
end
end
try this message options because the error should be your notification syntax.
options = {
priority: 'high',
data: {
message: "Hai",
location: location
},
notification: {
body: "Hai",
location: "location",
sound: 'default'
}
}

Firebase Authentication API Email/Password Android

I am attempting to write an app for android that uses Firebase Authentication via Email/Password. It is enabled. However the tutorial, and the code in Github for the examples are showing:
private FirebaseAuth mAuth;
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.google.firebase:firebase-core:9.0.2'
}
apply plugin: 'com.google.gms.google-services'
However, I get an error as if the "FirebaseAuth" doesn't exist. However the latest documentation says otherwise.
Github sample code
Any help would be greatly appreciated.
Replace the com.google.firebase:firebase-core:9.0.2' dependency with the com.google.firebase:firebase-auth:9.0.2 dependency. So:
compile 'com.google.firebase:firebase-auth:9.0.2'
instead of
compile 'com.google.firebase:firebase-core:9.0.2' under your dependencies.
I did not find the FirebaseAuth class in the core dependency but I did find it in the auth dependency. Furthermore, if you checkout their dependencies list, they do not add the core dependency, they add the auth dependency instead.
According to documentation in the firebase web page you should create a Firebase object using the URL from your firebase and from there create usernames with passwords or log them in. The code you showed used this FirebaseAuth for that.
Here is the code to create a new user:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.createUser("bobtony#firebase.com", "correcthorsebatterystaple", new Firebase.ValueResultHandler<Map<String, Object>>() {
#Override
public void onSuccess(Map<String, Object> result) {
System.out.println("Successfully created user account with uid: " + result.get("uid"));
}
#Override
public void onError(FirebaseError firebaseError) {
// there was an error
}
});
Here is the code to log him in:
Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.authWithPassword("bobtony#firebase.com", "correcthorsebatterystaple", new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
System.out.println("User ID: " + authData.getUid() + ", Provider: " + authData.getProvider());
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
// there was an error
}
});
Got all of this info from the quick start guide here: https://www.firebase.com/docs/android/guide/login/password.html#section-logging-in
Hope it helps.

Categories

Resources