How to maintain session in React Native Apps? - android

Can anybody tell me how to maintain session for a user login. For example when the user sign-in to an application they have to be signed in unless the user logouts or uninstall the application.

Use AsyncStorage.
Example:
For save:
AsyncStorage.multiSet([
["email", userInfo.email],
["password", userInfo.password]
])
For Delete:
let keys = ['email', 'password'];
AsyncStorage.multiRemove(keys, (err) => {
console.log('Local storage user info removed!');
});
For Get:
AsyncStorage.multiGet(['email', 'password']).then((data) => {
let email = data[0][1];
let password = data[1][1];
if (email !== null)
//Your logic
});
Important - password should be encrypted

Normally,there will be a session duration maintained in the server.Like for example say 1 hour.So every time when the app launches,call the login api and create a session.When the user first login,save the email and password in NSUserDefaults and whenever the session expires,the next api call will return a session specific error code (say like for example:401 error),Then get the values from NSUserDefaults and login automatically.
Also clear the NSUserDefaults and all other user related values on logout.

Related

How can I get Realtime update from firestore in my react-native application? I want to prevent multiple logs in from same user from different devices

I am working on one app in react-native. I want to do this kind of functionality.
1)When the user will log in from 1st device with their credential at that time I am storing device ID in my firestore database.
now, If the user will do sign in from 2nd device with the same credential at that time I am going to log out that user from 1st device. I have implemented that logic.
But the issue is this is not happening in real-time. When I will restart the 1st device's application at that time this logic works.
Is there any type of method that triggers when my database updates?
I want this logic to works immediately when the user logs in from another device with the same ID.
const onAuthStateChanged = async (user) => {
setUser(user);
if (user) {
//here i am checking for token
await firestore()
.collection('Users')
.doc(user.email)
.get()
.then((documentSnapshot) => {
const data_device = documentSnapshot.data();
if (device_id != data_device.device_token) {
alert('you are signned in other device'); //and if not as same then logout
logout();
}
});
}
if (inisiallizing) setInisiallizing(false);
};
The onAuthStateChanged only run when the authState changed (Login, logout, register) and its state is run on it own (not run in multiple environment, devices).
As your usecase, I think you should listen to a documents on Firestore that store your deviceId
firestore()
.collection('Users')
.doc(user.email)
.onSnapshot((doc) => {
// Your logic to logout here
})
The above code will run everytime document firestore().collection('Users').doc(user.email) has update

Is there any way to check if a user is new in flutter firebase (A facebook user)?

I'm looking for a way to check if a user just registered or is just signing in and there is no obvious way to do that with firebase and flutter with facebook authentication
The best I found is to compare the lastSignInTimestamp and creationTimestamp in the user's metadata. If they're the same or close to each other, this is likely the use's first sign in.
class AuthResult has AdditionalUserInfo which has isNewUser boolean which gives you this information.
https://pub.dev/documentation/firebase_auth/latest/firebase_auth/AuthResult-class.html
https://pub.dev/documentation/firebase_auth/latest/firebase_auth/AdditionalUserInfo-class.html
You should use the FlutterFire plugins found here.
Specifically, the authentication package will help you manage this:
https://github.com/flutter/plugins/tree/master/packages/firebase_auth
This bit of code will let you know whether there is a currentUser or not. Something along these lines.
final FirebaseAuth _auth = FirebaseAuth.instance;
final FirebaseUser currentUser = await _auth.currentUser();
if (user != null) {
_message = 'Successfully signed in, uid: ' + user.uid;
} else {
_message = 'Sign in failed';
}
Specific credential authentication with Facebook/Firestore:
https://github.com/flutter/plugins/blob/master/packages/firebase_auth/lib/src/auth_provider/facebook_auth_provider.dart
You need to have the Facebook SDK imported as well and pass the credential there. Firebase login/registration calls handle the rest and then pass back a Firebase user, which you can then use to store your own type of user if needed (which seems like what you are looking for).

Firebase Cloud Functions - Function triggered when user logged in [duplicate]

I see how execute a Cloud Function on user account creation:
exports.myFunction = functions.auth.user().onCreate(event => {
But I need my function to execute when the user logs in. Is there a onLogin trigger?
And can someone with 1500 points create a tag for firebase-cloud-functions?
There's no event for login, because only the client side can define exactly when a login happens. Different clients may define this in different ways. If you need to trigger something on login, figure out when that point is in your app, then trigger it from the client via a database or HTTP function.
This worked in the controller:
firebase.auth().onAuthStateChanged(function(user) { // this runs on login
if (user) { // user is signed in
console.log("User signed in!");
$scope.authData = user;
firebase.database().ref('userLoginEvent').update({'user': user.uid}); // update Firebase database to trigger Cloud Function
} // end if user is signed in
else { // User is signed out
console.log("User signed out.");
}
}); // end onAuthStateChanged
And this is the trigger in the Cloud Function:
exports.getWatsonToken = functions.database.ref('userLoginEvent').onUpdate(event => { // authentication trigger when user logs in
I made a location in Firebase Database called userLoginEvent.
One confusing bit is that in the functions console it's /userLoginEvent but in your code you must leave out the slash.
You can create your own analytics event, like login and used it as the trigger for your cloud function.
Then in your app, when the user successfully authenticate you use firebase analytics to send an event with the name you defined, like login
exports.sendCouponOnPurchase = functions.analytics.event('login').onLog((event) => {
const user = event.user;
const uid = user.userId; // The user ID set via the setUserId API.
});
You can trigger an https onCall firebase cloud function on login
ex: This is your login button trigger function which calls an https onCall function after authenticating the user.
_login() {
firebase
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.then(function (user) {
var addMessage = firebase.functions().httpsCallable('myCloudFunctionName');
addMessage("whatever variable I want to pass")
.catch(error => {
console.log("I triggered because of an error in addMessage firebase function " + error)
)}
}).catch(error => {
console.log(error);
});
}
There is also another way you can do this inside Google Cloud if you enable Identity Platform for a project. Then you can follow this guide:
https://cloud.google.com/functions/docs/calling/logging
And trigger cloud functions for any of these Firebase Authentication events:
https://cloud.google.com/identity-platform/docs/activity-logging?authuser=1&_ga=2.226566175.-360767162.1535709791#logged_operations
The only problem I've just noticed is that the logs generated for Sign In event do not include the firebase app id or anything to determine which client the user logged in on which is really annoying as this was the main reason we needed to do this!

Android native app authentification with WordPress users

I am making a native Android app. I have a WordPress website with a few users. I want my WordPress user to log in my app using the same login and password. I would like a very fluent login process without any webview or web browser.
Is it possible ? What would you recommend ?
Yes it is possible. All actions you want to preform from app side, i recommend to add those actions as ajax functions on wordpress side (it is much cleaner and organized that way - and you can base your communication on json like that ). Regarding logic, you can achieve it using two different ways:
Lets say that you want to implement an application which will allow user to, register, login, and create posts.
1st way
class App {
public function __construct(){
add_action( 'wp_ajax_nopriv_registerUser', array( $this, 'registerUser' ) );
add_action( 'wp_ajax_nopriv_loginUser', array( $this, 'loginUser' ) );
add_action( 'wp_ajax_nopriv_createPost', array( $this, 'createPost' ) );
}
public function registerUser() {
//obviusly, you dont need any kind of auth over here
}
public function loginUser() {
$username = //collect,sanitize data from post
$password = //collect data from post
$user = get_user_by( 'login', $username );
if( wp_check_password( $password, $user->user_pass ) ) {
//preform what you need to preform
//construct successful result array
}
else {
//populate result array with an error or something
}
wp_send_json( $result );
}
public function createPost() {
$username = //collect,sanitize data from post
$password = //collect data from post
//collect rest of the data related with post by itself
$user = get_user_by( 'login', $username );
if( wp_check_password( $password, $user->user_pass ) ) {
//insert post, construct successfully array
}
else {
//populate result array with an error or something
}
wp_send_json($result);
}
}
As you can see in example above, you can register as much ajax functions as you want and within each of those you can have user check and password check which is going to work just fine. Point is that, for each action you want to preform from your mobile app, you will need to send an username/password (you can store these on first successful login on app side) with other parameters.
2nd way
Same example above, with one difference. You can (during first login request from app side), on php side generate unique guid which you can save inside wp database, and return it to your app side (where you can save it on your app side). For each next request, you can send that guid and username from app side, confirming that user is already login and can preform privileged actions. There is no a lot of difference (from perspective of performance, I think that in both of the cases you will need to execute one query only - from perspective of auth, you can preform some testing in order to confirm this WP_User class ). Second method is valuable if you need to identify different login sessions from one end to another (if application crashed and you want to check on your side does user want to preform login while he/she is already "logged in", or you want to forbid login in from more then one application per user. )

Sinatra + omniauth + Android, advice sought

I'm developing a Sinatra app for which I'd like to use OmniAuth. So far, I have something similar to this for the web app:
http://codebiff.com/omniauth-with-sinatra
I'd like the web app to be usable via Android phones which would use an API, authenticating by means of a token. The development of an API seems to be covered nicely here:
Sinatra - API - Authentication
What is not clear is now I might arrange the login procedure. Presumably it would be along these lines:
User selects what service to use, e.g. Twitter, FaceBook &c., by means of an in-app button on the Android device.
The Android app opens a webview to log in to the web app.
A token is somehow created, stored in the web app's database, and returned to the Android app so that it can be stored and used for subsequent API requests.
I'm not very clear on how point 3 might be managed - does anyone have any suggestions?
As no-one seems to have any suggestions, here's what I've come up with so far. I don't think it's very good, though.
I've added an API key to the user model, which is created when the user is first authenticated:
class User
include DataMapper::Resource
property :id, Serial, :key => true
property :uid, String
property :name, String
property :nickname, String
property :created_at, DateTime
property :api_key, String, :key => true
end
....
get '/auth/:name/callback' do
auth = request.env["omniauth.auth"]
user = User.first_or_create({ :uid => auth["uid"]},
{ :uid => auth["uid"],
:nickname => auth["info"]["nickname"],
:name => auth["info"]["name"],
:api_key => SecureRandom.hex(20),
:created_at => Time.now })
session[:user_id] = user.id
session[:api_key] = user.api_key
flash[:info] = "Welcome, #{user.name}"
redirect "/success/#{user.id}/#{user.api_key}"
end
If the authorisation works then the api_key is supplied to the Android app, which will presumably store it on the device somewhere:
get '/success/:id/:api_key', :check => :valid_key? do
user = User.get(params[:id],params[:api_key])
if user.api_key == params[:api_key]
{'api_key' => user.api_key}.to_json
else
error 401
end
end
All API calls are protected as in the link in my original post:
register do
def check (name)
condition do
error 401 unless send(name) == true
end
end
end
helpers do
def valid_key?
user = User.first(:api_key => params[:api_key])
if !user.nil?
return true
end
return false
end
end
For public use I'll only allow SSL connections to the server. Any suggestions for improvement would be welcome.

Categories

Resources