I'm not sure if this is the right place to ask for flow-related question. Do guide me if you're aware of a better section.
I'm currently doing a web based system for multiple organizations, so on my login form, there's 3 simple field:
Company code, such as CNN (so we can have same username, as long as they work in different company)
Username, such as james
Password
Now we are actually studying on the fingerprint authentication technology, on how it could help above.
Our assumption is below:
On our app, we provide user a registration screen, instead of username/password, they tap their thumb on the form, so we can get something, maybe a lengthy random string, which represents the thumbprint, then we pass this code to server, along with his profile, and registration completes.
Above repeats for thousands of our other users.
A user came to our app login screen, we show them a scanner, they put their thumbs on it, we send the retrieved fingerprint code, and send to server for a matching comparison, then we authenticate this user.
But from what we studied, it seems that the fingerprint SDK doesn't works this way, it simply authenticate if the user is the owner of the phone, and it does not provide us a code or something to represents the fingerprint.
Can anyone with experience in developing a working/deployed fingerprint app, share with me how does fingerprint helps in authenticating your user?
Thank you.
you should add this line in your manifest.xml - <uses-feature
android:name="android.hardware.fingerprint"
android:required="false" />
Here is the code sample to show fingerprint dialog and get result from user interaction:
private void showFingerPrintDialog() {
final FingerprintDialogBuilder dialogBuilder = new FingerprintDialogBuilder(ContextInstance)
.setTitle(R.string.fingerprint_dialog_title)
.setSubtitle(R.string.fingerprint_dialog_subtitle)
.setDescription(R.string.fingerprint_dialog_description)
.setNegativeButton(R.string.cancel);
dialogBuilder.show(getSupportFragmentManager(), new AuthenticationCallback() {
#Override
public void fingerprintAuthenticationNotSupported() {
Log.d(TAG, "fingerprintAuthenticationNotSupported: ");
}
#Override
public void hasNoFingerprintEnrolled() {
Log.d(TAG, "hasNoFingerprintEnrolled: ");
}
#Override
public void onAuthenticationError(int errorCode, #Nullable CharSequence errString) {
Log.d(TAG, "onAuthenticationError: ");
}
#Override
public void onAuthenticationHelp(int helpCode, #Nullable CharSequence helpString) {
Log.d(TAG, "onAuthenticationHelp: ");
}
#Override
public void authenticationCanceledByUser() {
Log.d(TAG, "authenticationCanceledByUser: ");
}
#Override
public void onAuthenticationSucceeded() {
Log.d(TAG, "onAuthenticationSucceeded: ");
/*SaveResult in db or preference*/
}
#Override
public void onAuthenticationFailed() {
Log.d(TAG, "onAuthenticationFailed: ");
}
});
}
Related
I am having an issue with AppsFlyer Android SDK AppsFlyerInAppPurchaseValidatorListener class.
AppsFlyerLib.getInstance().registerValidatorListener(this,new
AppsFlyerInAppPurchaseValidatorListener() {
public void onValidateInApp() {
Log.d(TAG, "Purchase validated successfully");
}
public void onValidateInAppFailure(String error) {
Log.d(TAG, "onValidateInAppFailure called: " + error);
}
});
Currently there is no way to detect which particular purchase transaction was successful with this listener. So for example, if I am validating multiple purchase transactions from a Google Billing Client queryPurchasesAsync call. This listener will not tell me which specific purchase transaction was successful or failed.
The closest solution to this that I found was at:
AppsFlyerAndroidWrapper.java
public static void validateAndTrackInAppPurchase (String publicKey, String signature, String purchaseData, String price, String currency, HashMap<String, String> additionalParameters, String objectName)
{
AppsFlyerLib.getInstance().validateAndLogInAppPurchase(UnityPlayer.currentActivity,
publicKey, signature, purchaseData, price, currency, additionalParameters);
if (objectName != null)
{
initInAppPurchaseValidatorListener(objectName);
}
}
public static void initInAppPurchaseValidatorListener(final String objectName)
{
AppsFlyerLib.getInstance().registerValidatorListener(UnityPlayer.currentActivity, new
AppsFlyerInAppPurchaseValidatorListener()
{
#Override
public void onValidateInApp() {
if(objectName != null){
UnityPlayer.UnitySendMessage(objectName, VALIDATE_CALLBACK, "Validate
success");
}
}
#Override
public void onValidateInAppFailure(String error) {
if(objectName != null){
UnityPlayer.UnitySendMessage(objectName, VALIDATE_ERROR_CALLBACK, error);
}
}
});
}
Here it looks like they instantiate a new validator listener for each call to validateAndLogInAppPurchase. However, will that not just get rid of the previous validator listener that was instantiated? To me it looks like you can only register ONE validator listener at a time with AppsFlyer. There is no way to tie a particular validator listener to a specific validateAndLogInAppPurchase call. I've searched high and low and have not been able to find a definitive answer to this question so any pointers anyone has would be greatly appreciated.
Thanks
I have searched through github, the Appsflyer Android SDK samples and this particular situation is never addressed. In particular there are no Android SDK samples that tackle this issue so it may be that support for multiple transaction validations is not supported by the Appsflyer Android SDK.
I implemented the snapchat login in my Android app by referring to the snapchat login kit sdk guide.
I refer to the below code that uses a custom button.
// Get the login API
SnapLogin snapLogin = SnapLoginProvider.get(getContext());
View yourButtonView = findViewById(...);
yourButtonView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Start token grant
snapLogin.startTokenGrant(new LoginResultCallback() {
#Override
public void onStart() {
// Here you could update the UI to show login start
}
#Override
public void onSuccess(#NonNull String accessToken) {
// Here you could update the UI to show login success
}
#Override
public void onFailure(#NonNull LoginException exception) {
// Here you could update the UI to show login failure
}
});
}
});
Call startTokenGrant api to complete authentication in snapchat.
After authentication, callback is called when returning to my app.
Step 1 goes well.
But intermittently, the callback is not called.
I thought this was an error in the sdk, but I saw that it works normally in other apps.
Has anyone had an experience where the callback never gets called?
If yes, please help how to solve it.
(I'm developing using dev clientId right now, will this have any effect?)
I am implementing AWS with an Android application for the first time.
We would like to use Cognito to authenticate our users, and selectively provide data from DynamoDB.
I have successfully set up my user pool and can see new registrations appear in the user list. Trying to login with an email that does not exist fails.
However, Cognito always logs in with a valid email address, regardless of password input.
What is wrong with my process?
public class CognitoController extends Application {
static CognitoUserPool pool;
static String userEmail;
public void onCreate(){
super.onCreate();
pool = new CognitoUserPool(this,
"us-east-xxxx",
"xxxx",
"xxxx",
new ClientConfiguration(),
Regions.US_EAST_1);
}
}
-
private void actionAdminLogin(){
UtilityInterfaceTools.hideSoftKeyboard(AdminLoginActivity.this);
String inputEmail = ((EditText) findViewById(R.id.input_admin_email)).getText().toString();
String inputPassword = ((EditText) findViewById(R.id.input_admin_password)).getText().toString();
CognitoController.userEmail = inputEmail;
details = new AuthenticationDetails(inputEmail, inputPassword, null);
AuthenticationHandler auther = new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
Toast.makeText(AdminLoginActivity.this, "Congratulations It Works...", Toast.LENGTH_LONG).show();
startActivity(new Intent(AdminLoginActivity.this, AdminPortalActivity.class));
finish();
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation continuation, String email) {
continuation.setAuthenticationDetails(details);
continuation.continueTask();
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
continuation.continueTask();
}
#Override
public void authenticationChallenge(ChallengeContinuation continuation) {
continuation.continueTask();
}
#Override
public void onFailure(Exception exception) {
TextView errorMessage = findViewById(R.id.message_invalid_credentials);
errorMessage.setText(exception.toString());
errorMessage.setVisibility(View.VISIBLE);
}
};
CognitoController.pool.getUser(inputEmail).getSessionInBackground(auther);
}
I think your problem (which is not a problem by the way) is either:
In your pool Cognito setting, you chose your devices to be remembered.
Remembered
devices are also tracked. During user authentication, the key and secret pair assigned to a remembered device is used to authenticate the device to verify that it is the same device that the user previously used to sign in to the application. APIs to see remembered devices have been added to new releases of the Android, iOS, and JavaScript SDKs. You can also see remembered devices from the Amazon Cognito console.
The token is already cached:
Caching
The Mobile SDK for Android caches the last successfully authenticated user and the user's tokens locally on the device, in SharedPreferences. The SDK also provides methods to get the last successfully authenticated user.
Your Application Update
In fact for better user experience, you want the user to use the app, and don't need to login every time that she wants to use your app (e.g., look at mail apps, social media apps, etc.). However, you application need to handle that, you have two choices here:
Redirect to login if necessary: If the user is already logged in and wants to use the application again, your app needs to verify the user against the Cognito user pool, and only then, redirect the user to the login page if necessary.
Remove the token: If you really want the user to login every time that she uses the application, then remove the token if the user signs out; but I do not recommend this, for the sake of user experience.
I have registered one user using AWS Cognito android SDK. I am login with user on one device and I am able to fetch all the attributes of the user.But when I log in with same user on different device it gives me CognitoNotAuthorizedException (user is not authenticated message) and I am not able to fetch the attributes.
I have checked on Cognito user pool and the user has been registered and confirmed also phone number has been verified.Is there any version specification for getUserDetails() method which I am missing.I also ran signup/login/forgot password functionality on second device and all are working fine except getUserDetail.Below Code I am using for getting user details.
private void getDetails() {
AppHelper.getPool().getUser(mUsername).getDetailsInBackground(detailsHandler);
}
GetDetailsHandler detailsHandler = new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
AppHelper.setUserDetails(cognitoUserDetails);
}
#Override
public void onFailure(Exception exception) {
showDialogMessage(getString(R.string.could_not_fetch_user_data), AppHelper.formatException(exception), true);
}
};
I'm trying to integrate Pinterest into an android application and I would like to retrieve all the pins for a specific user (obviously after the user has logged in). Is this possible to be achieved by utilising the api released by Pinterest? Many thanks.
Yes, this is possible, check Pinterest sample app on GitHub:
link
sample code:
private void fetchPins() {
adapter.setPinList(null);
adapter.notifyDataSetChanged();
PDKClient.getInstance().getMyPins(PIN_FIELDS, new PDKCallback() {
#Override
public void onSuccess(PDKResponse response) {
List<PDKPin> list=new Arraylist<>;
//getting pin list
list=response.getPinList();
}
#Override
public void onFailure(PDKException exception) {
_loading = false;
Log.e(getClass().getName(), exception.getDetailMessage());
}
}
);
}
Happy coding!