Hello everyone i am working with http://quickblox.com/developers/Sample-webrtc-android its works fine
But i want know that is there any way to keep user logged in as quick blox user in my app.
Because right now everytime user open my app user have to login first so i want to keep session alive if it is possible android,
Because its better to do for performance instead of everytime login just prevent to login and keep session alive
Thanks in advance
I have used below code
private void createSession(final String login, final String password) {
final QBUser user = new QBUser(login, password);
QBAuth.createSession(login, password, new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle bundle) {
Log.d(TAG, "onSuccess create session with params");
user.setId(session.getUserId());
if (chatService.isLoggedIn()) {
initQBRTCClient();
} else {
chatService.login(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess() {
Log.d(TAG, "onSuccess login to chat");
/*
* ListUsersActivity.this .runOnUiThread(new
* Runnable() {
*
* #Override public void run() {
* showProgress(false); } });
*
* startCallActivity(login);
*/
islogin = true;
initQBRTCClient();
}
#Override
public void onError(List errors) {
Toast.makeText(HomeAppActivity.this, "Error when login", Toast.LENGTH_SHORT).show();
for (Object error : errors) {
Log.d(TAG, error.toString());
}
}
});
}
}
#Override
public void onError(List<String> errors) {
Toast.makeText(HomeAppActivity.this, "Error when login, check test users login and password",
Toast.LENGTH_SHORT).show();
}
});
}
As described in documentation session token is valid for 2 hours.
Once you have logged, you can store session token & expiration time somewhere in app storage - preference, database, etc. Token can be retrieved by BaseService.getBaseService().getToken().
When user opens your app again, you can set session using stored token BaseService.createFromExistentToken()
Here is the documentation.
Also to keep running permanently chat connection it’s better to use android service.
Related
I was integrating azure adb2c on my native android app using MSAL. My token expiry is set to 60minutes in the portal. Currently I'm calling the acquireTokenSilentAsync each time the app launches in order to make sure access token is not expired. But is there any way to avoid calling acquireTokenSilentAsync each time and make the call happens only when the access token expires? This is to make the app load much faster,by avoid calling acquireTokenSilentAsync every time.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.microsoft_azure);
context = MicrosoftAzureActivity.this;
initializeUI();
// Creates a PublicClientApplication object with res/raw/auth_config_single_account.json
PublicClientApplication.createSingleAccountPublicClientApplication(MicrosoftAzureActivity.this,
R.raw.auth_config_single_account,
new IPublicClientApplication.ISingleAccountApplicationCreatedListener() {
#Override
public void onCreated(ISingleAccountPublicClientApplication application) {
/**
* This test app assumes that the app is only going to support one account.
* This requires "account_mode" : "SINGLE" in the config json file.
**/
loadAccount();
}
#Override
public void onError(MsalException exception) {
displayError(exception);
}
});
}
Interactively fetching Token:
mSingleAccountApp.signIn(MicrosoftAzureActivity.this, null, getScopes(), getAuthInteractiveCallback());
Load Account when already token is fetched Interactively and account is already Loaded:
private void loadAccount() {
if (mSingleAccountApp == null) {
Log.d("SKT","Account Not Signed In");
return;
}
Log.d("SKT","Account Not Signed In#1");
mSingleAccountApp.getCurrentAccountAsync(new ISingleAccountPublicClientApplication.CurrentAccountCallback() {
#Override
public void onAccountLoaded(#Nullable IAccount activeAccount) {
// You can use the account data to update your UI or your app database.
mAccount = activeAccount;
if (activeAccount != null) {
Log.d("SKT","Account Already Signed In");
mSingleAccountApp.acquireTokenSilentAsync(getScopes(), B2CConfiguration.getAuthorityFromPolicyName("B2C_1_SignInSignUp"), getAuthSilentCallback());
}
}
#Override
public void onAccountChanged(#Nullable IAccount priorAccount, #Nullable IAccount currentAccount) {
if (currentAccount == null) {
// Perform a cleanup task as the signed-in account changed.
showToastOnSignOut();
}
}
#Override
public void onError(#NonNull MsalException exception) {
displayError(exception);
}
});
}
No, you must call acquireTokenAsync for this, it evaluates whether the token in cache is expired or for a different scope than being requested. If neither is true, MSAL returns the tokens from the cache, it doesn’t make any network calls and should be almost instant. You wouldn’t get any perf advantage by doing anything different as that is the minimum.
I've set up a user pool for a mobile application. The sign up process works as expected, however, attempting to log in the user in results in the following Exception:
User login alias should not be null (Service:
AmazonCognitoIdentityProvider; Status Code: 400; Error Code:
InvalidParameterException; Request ID: xxx....)
This error is being produced during the sign in attempt, called via:
CognitoUserPool.getUser(username).getSessionInBackground(authenticationHandler);
To provide a fuller snippet of the code, when the user clicks the login button, a function containing the following code is run:
AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
#Override
public void onSuccess(CognitoUserSession userSession) {
Util.showMessage(mContext, "User Successfully Signed In. Session JWT Token: " + userSession.getIdToken().getJWTToken());
btnLogin.setProgress(100);
}
#Override
public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String UserId) {
AuthenticationDetails authenticationDetails = new AuthenticationDetails(UserId, edtPassword.getText().toString().trim(), null);
authenticationContinuation.setAuthenticationDetails(authenticationDetails);
authenticationContinuation.continueTask();
}
#Override
public void getMFACode(MultiFactorAuthenticationContinuation continuation) {
Util.showMessage(mContext, "MFA Code is Required");
// Set Up MFA Process
}
#Override
public void onFailure(Exception exception) {
Log.d(TAG, exception.toString());
Snackbar.make(edtUsername, exception.getMessage(), Snackbar.LENGTH_LONG).show();
btnLogin.setProgress(-1);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setUpLoginClick();
}
}, 1000);
}
};
AWS.userPool(mContext).getUser(edtUsername.getText().toString()).getSessionInBackground(authenticationHandler);
AWS.userPool(Context ctx) is a utility function that i wrote to quickly retrieve the configured UserPool object.
Can anyone shed some light on why this might be happening? I can't find discussion or documentation of this error anywhere.
I am developing an app in Android using firebase.I have created the login activity where i have a method that logs user in when they pass the credentials(user creation is already done).Then i will save the token recieved in onAuthenticated callback so that i can log user in automatically next time when he/she opens the app without asking to enter the credentials.
Here is the code
private void loginWithPassword(final String email, String password) {
progressDialog.show();
FirebaseConnections.getConnection().authWithPassword(email, password,
new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
// Authentication just completed successfully :)
IGStorePreference.getInstance().saveString(Constants.TOKEN, authData.getToken());
IGStorePreference.getInstance().saveString(Constants.UID, authData.getUid());
IGStorePreference.getInstance().saveString(Constants.PROVIDER, authData.getProvider());
dismissProgressDialog();
}
#Override
public void onAuthenticationError(FirebaseError error) {
// Something went wrong :(
dismissProgressDialog();
Snackbar.make(parentView, error.getMessage(), Snackbar.LENGTH_LONG).show();
}
});
}
And then i check onCreate whether we have token token to log user in
private void checkIfTokenExistAndLogin() {
if (IGStorePreference.getInstance().isPrefExists(Constants.TOKEN)) {
progressDialog.show();
String provider = IGStorePreference.getInstance().getString(Constants.PROVIDER);
String token = IGStorePreference.getInstance().getString(Constants.TOKEN);
FirebaseConnections.getConnection().authWithOAuthToken(provider, token, new Firebase.AuthResultHandler() {
#Override
public void onAuthenticated(AuthData authData) {
IGStorePreference.getInstance().saveString(Constants.TOKEN, authData.getToken());
IGStorePreference.getInstance().saveString(Constants.UID, authData.getUid());
IGStorePreference.getInstance().saveString(Constants.PROVIDER, authData.getProvider());
dismissProgressDialog();
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
dismissProgressDialog();
Snackbar.make(parentView, firebaseError.getMessage(), Snackbar.LENGTH_LONG).show();
}
});
}
}
But the problem is that i am getting an error while login user with authWithOAuthToken.Please help what i am missing.
This is the error i recieve everytime.
FirebaseError: Invalid authentication credentials provided.
authWithOAuthToken is used to login with a social provider. For example, user signs in with Google and gets an OAuth token returned from Google. Then app sends this OAuth token to Firebase auth server via authWithOAuthToken. User can log in after server verifies the OAuth token.
In your case, user logged in with email/password. The token you received was a Firebase auth token issued by Firebase auth server not an OAuth token issued by social provider.
Please refer to the doc for details: https://firebase.google.com/support/guides/firebase-android#sign_a_user_in_with_a_social_provider_numbered
I've spent the better part of 2 days trying to understand and follow the "Getting Started" section in the Android SDK doc (I'm a noob, so please go slow). I've also been picking through Quickblox API documentation, Stack overflow Quickblox Q&A's, and the Quickblox sample code.
Could someone please explain how I can actually establish a very simple and basic session with the Quickblox backend?
In trying to do this myself, here's what's I've run into/discovered:
Under the section "Getting Started" (in http://quickblox.com/developers/Android) the following steps are outlined:
Initialize framework with application credentials
Create session
Login with existing user or register new one
Perform actions with QuickBlox communication services and any data entities (users, locations, files, custom objects, pushes etc.)
For #1 above, it gives the following code:
QBSettings.getInstance().fastConfigInit("961", "PBZxXW3WgGZtFZv", "vvHjRbVFF6mmeyJ");
I put the above in the OnCreate method of my activity.
Then, for #2, it says "To create an application session use this code:"
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
}
#Override
public void onError(List<String> errors) {
// errors
}
});
I also add that to my OnCreate.
For #3, I continue to use the suggested code. Is this case, I am creating a new user:
// Register new user
final QBUser user = new QBUser("userlogin", "userpassword");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
}
#Override
public void onError(List<String> errors) {
// error
}
});
Here's my full OnCreate code:
public class ChatCategoryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat_category);
Toast.makeText(getApplicationContext(), "Toast Test!",
Toast.LENGTH_LONG).show();
//Initialize quickblox framework
QBSettings.getInstance().fastConfigInit("29430", "XNKu54nymZXFq3c", "3vy372mwtYwfJU7");
//create a quickblox application session
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
Toast.makeText(getApplicationContext(), "App session created!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// errors
Toast.makeText(getApplicationContext(), "Failed to create app session!",
Toast.LENGTH_LONG).show();
}
});
// Register new user
final QBUser user = new QBUser("bob1", "bobobob1");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
Toast.makeText(getApplicationContext(), "User signed up!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// error
Toast.makeText(getApplicationContext(), "User sign-up failed!",
Toast.LENGTH_LONG).show();
}
});
}
}
So, when I run it, according to the toast that fires, the app session fails to be created. Additionally, the URL that the app posts is this:
https://api.quickblox.com/session.json?application_id=29430&auth_key=XNKu54nymZXFq3c&nonce=166079749×tamp=1444750770&signature=a412ecb12db54842f6816968a734b4fc2626509d
And the response is:
{"errors":["Token is required"]}
The only place a "token" is mentioned in the Android SDK doc is here:
It's also possible to initialise the SDK with an existent QuickBlox
token. It can be interesting in cases when you build a big system and
you have the server side which generates QuickBlox tokens for
example...
The implication is that the token is not necessary. But clearly it is.
Could someone please help me with what what I am missing? I'd be very grateful for the code I need, including how to generate the token (including the SHA signature) and use it to initialise the framework, create a session, create/login a user, etc....
Many thanks!
First check: internet connection, do you have the internet permission in your manifest?
<uses-permission android:name="android.permission.INTERNET"/>
Your code to create session and user looks fine but you can only sign up once the session is created !
Using your code it would looks like that :
public class ChatCategoryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initialize quickblox framework
QBSettings.getInstance().fastConfigInit("29430", "XNKu54nymZXFq3c", "3vy372mwtYwfJU7");
//create a quickblox application session
QBAuth.createSession(new QBEntityCallbackImpl<QBSession>() {
#Override
public void onSuccess(QBSession session, Bundle params) {
// success
Toast.makeText(getApplicationContext(), "App session created!",
Toast.LENGTH_LONG).show();
// Register new user
final QBUser user = new QBUser("bob1", "bobobob1");
QBUsers.signUp(user, new QBEntityCallbackImpl<QBUser>() {
#Override
public void onSuccess(QBUser user, Bundle args) {
// success
Toast.makeText(getApplicationContext(), "User signed up!",
Toast.LENGTH_LONG).show();
}
#Override
public void onError(List<String> errors) {
// error
Toast.makeText(getApplicationContext(), "User sign-up failed!",
Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onError(List<String> errors) {
// errors
Toast.makeText(getApplicationContext(), "Failed to create app session!",
Toast.LENGTH_LONG).show();
}
});
}
}
If the credentials are OK, a new user should be created. (for security reasons don't forget to reset the credentials and update your code.)
I'm using Firebase SimpleLogin to enable Email / Password authentication. Creation of users and subsequent login is all working fine. However, whenever I leave the app (even if only for a few seconds) the user is never logged in on my return i.e...
authClient.checkAuthStatus(new SimpleLoginAuthenticatedHandler())...
Always returns a null user.
I am not logging out the user via the API. Also I have set the number of days the user is logged in to 21 in the Firebase console.
I have seen mention of a remember-me param in the JS docs, but I can't see any equivalent for Android / Java.
Wondering if I'm missing anything in the docs or if it's not possible for Android?
Thanks for your help,
Neil.
Edit: Added code sample.
User creation....
public void registerUserForChat(final MyApplication application, String email, String password) {
Firebase ref = new Firebase(FIREBASE_URL);
SimpleLogin authClient = new SimpleLogin(ref);
authClient.createUser(email, password, new SimpleLoginAuthenticatedHandler() {
#Override
public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
if(error != null) {
Log.e(TAG, "Error attempting to create new Firebase User: " + error);
}
else {
Log.d(TAG, "User successfully registered for Firebase");
application.setLoggedIntoChat(true);
}
}
});
}
User login....
public void loginUserForChat(final MyApplication application, String email, String password) {
Log.d(TAG, "Attempting to login Firebase user...");
Firebase ref = new Firebase(FirebaseService.FIREBASE_URL);
final SimpleLogin authClient = new SimpleLogin(ref);
authClient.checkAuthStatus(new SimpleLoginAuthenticatedHandler() {
#Override
public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
if (error != null) {
Log.d(TAG, "error performing check: " + error);
} else if (user == null) {
Log.d(TAG, "no user logged in. Will login...");
authClient.loginWithEmail(email, password, new SimpleLoginAuthenticatedHandler() {
#Override
public void authenticated(com.firebase.simplelogin.enums.Error error, User user) {
if(error != null) {
if(com.firebase.simplelogin.enums.Error.UserDoesNotExist == error) {
Log.e(TAG, "UserDoesNotExist!");
} else {
Log.e(TAG, "Error attempting to login Firebase User: " + error);
}
}
else {
Log.d(TAG, "User successfully logged into Firebase");
application.setLoggedIntoChat(true);
}
}
});
} else {
Log.d(TAG, "user is logged in");
}
}
});
}
So loginUserForChat method first checks to see if there is a logged in user and, if not, performs the login. Note that every time I start the app, the logging I see is....
Attempting to login Firebase user...
no user logged in. Will login...
User successfully logged into Firebase
If I exit the app, even for a few seconds, and return - I see the same logging.
One thing I noticed is that the call to checkAuthStatus does not take any user credentials - I assume it just checks for any locally logged in user?
Much appreciated.
Another way - try this code in your onCreate:
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
// User is signed in
Intent i = new Intent(LoginActivity.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
} else {
// User is signed out
Log.d(TAG, "onAuthStateChanged:signed_out");
}
This will keep the user logged in by taking the user to the Main activity directly without stopping at registration activity. so the user will be logged in unless the user click on signout.
[Engineer at Firebase] In order to transparently handle persistent sessions in the Firebase Simple Login Java client, you need to use the two-argument constructor which accepts an Android context, i.e. SimpleLogin(com.firebase.client.Firebase ref, android.content.Context context) every time you instantiate the Simple Login Java client.
See https://www.firebase.com/docs/java-simple-login-api/javadoc/com/firebase/simplelogin/SimpleLogin.html for the full API reference.
The proper way to do it is to use oAuth authentication:
1. The user logs in.
2. You generate an access token(oAuth2).
3. Android app saves the token locally.
4. Each time the comes back to the auth, he can use the token to to log in, unless the token has been revoked by you, or he changed his
password.
Luckily, firebase has an out of the box support for that, docs:
https://www.firebase.com/docs/security/custom-login.html
https://www.firebase.com/docs/security/authentication.html
You can do this by Using this Approach to escape logi page if User already logged in.
private FirebaseAuth auth;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
auth = FirebaseAuth.getInstance();
if (auth.getCurrentUser() != null) {
startActivity(new Intent(Login_Activity.this, Home.class));
finish();
}
setContentView(R.layout.activity_login_);
for those using Kotlin, to keep the user logged in just add in the onCreate function
if (auth.currentUser != null)
{
startActivity(Intent(this#Login, SellingPageHolderActivity::class.java))
finish()
}