I have implemented the Akavache to work with my Xamarin.Android app. The saving and retrieval of keys work fine. I wanted to achieve a single sign on experience over two of my apps. I wanted to know if there is a way I can share the keys saved from one of my apps to the other app.
Some code I use for Key saving and retrieval.
BlobCache.ApplicationName = "IIMSuite";
await BlobCache.Secure.InsertObject("Token", authResult.Token);
await BlobCache.Secure.InsertObject("SavedUserEmail", userName);
await BlobCache.Secure.InsertObject("SavedUserName", userEmail);
try
{
userName = await BlobCache.Secure.GetObject<string>("SavedUserName");
userEmail = await BlobCache.Secure.GetObject<string>("SavedUserEmail");
token = await BlobCache.Secure.GetObject<string>("Token");
}
catch(KeyNotFoundException ex){}
I tried implementing the same code in the other app by keeping the BlobCache.ApplicationName consistent but that does not seem to work and does not retrieve any values.
Any help is appreciated.
Related
I have an iOS app already on Store, Now planning to replace it with Flutter with new version release.
I want to get access native app's UserDefaults data in Flutter code.
Using the way suggested in Flutter docs I m getting null value. What I have tried is:
In my pubspec.yaml file :
dependencies:
shared_preferences: ^0.5.12+4
Im my home.dart class file I'm importing header :
import 'package:shared_preferences/shared_preferences.dart';
And this is how I m trying to access data stored in iOS app from native app, I m using same bundle ID (Package ID) in flutter project to overwrite the app and it is successfully overwriting.
#override
void initState() {
super.initState();
getFromLocalMemory('user').then((value) =>
userInfo = value
);
}
Future<String> getFromLocalMemory(String key) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String user = prefs.getString(key);
return user;
}
It always returns null. While 'user' key has data when getting from iOS native app.
We can use existing plugin native_shared_preferences. It allows us to access native SharedPreferences on Android and UserDefaults on iOS.
Sample code to read a value by key "SomeKey":
final someKey = "SomeKey";
var prefs = await NativeSharedPreferences.getInstance();
if (prefs.containsKey(someKey)) {
print("Value for SomeKey: ${prefs.get(someKey)}");
}
In that case, I suggest you use platform channel method
platform channels
iOS doesn't seem to allow flutter framework to access NSUserDefaults, when it didn't create it from the beginning,..
I hope it will work for you.
I'm working on a school project that is a transportation application on android.
I'm trying to edit user information from another user as logged in. When I try to edit another user's saved variable, I get
java.lang.IllegalArgumentException: Cannot save a ParseUser that is
not authenticated.
On my search, I saw that some people recommend changing ACL to public write on the users to edit them, I tried that and unfortunately, It didn't change anything, I still have this error. Another advice was to use cloud code or master key but I couldn't find any documentation that shows how to implement them. I'd be glad if anyone helps me. Thank you very much.
you can use masterKey in cloud code like this:
otherUser.save(null,{useMasterKey:true});
Here is a complete example using cloud code and master key:
Parse.Cloud.define("saveOtherUser", async (request) => {
const otherUserID = request.params.otherUserID;//other user's ID;
const user = request.user; //This is you. We are NOT gonna update this.
//you can check your security with using this user. For example:
if(!user.get("admin")){
//we are checking if th requesting user has admin privaleges.
//Otherwise everyone who call this cloud code can change other users information.
throw "this operation requires admin privilages"
//and our cloud code terminates here. Below codes never run
//so other users information stays safe.
}
//We create other user
const otherUser = new Parse.User({id:otherUserID});
//Change variables
otherUser.set("variable","New Variable, New Value");
//Now we are going to save user
await otherUser.save(null,{useMasterKey:true});
//this is the response our android app will recieve
return true;
});
This is our Java code for android app:
HashMap<String, Object> params = new HashMap<>();
params.put("otherUserID", otherUser.getObjectId());
ParseCloud.callFunctionInBackground("saveOtherUser", params, new FunctionCallback<Boolean>() {
#Override
public void done(Boolean object, ParseException e) {
if(e==null&&object){
//save operation successful
}
else{
//save operation failed
}
}
});
Aklına takılan olursa sor :)
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).
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.
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.