store logged in user details in xamarin forms using SQLite - c#

I am working on Xamarin forms applicaiton which will have three welcome pages while the user is logging into the applicaiton for the first time, if the user user is trying to start the application after logging in only dashboard has to be displayed. I have written the following code for that :
public LoginUserInfoDbModel SaveUserDetails(LoginUserInfoDbModel model)
{
if(model.LoggedInUser!=null)
{
return null;
}
else
{
connection.Insert(model);
return model;
}
}
and called the above method in LoginPage.xaml.cs in the following way :
if (model.ResultString == "Valid")
{
App.UserDatabase.SaveUserDetails(model);
await DisplayAlert("", "You have logged in succesfully ", "Ok");
await Navigation.PushAsync(new DashBoardPage());
}
So now I need to check whether the User is already a existing user or not in DB, so I have written the following code in App.xaml.cs :
var connection = DependencyService.Get<ISQLiteDb>().GetConnection();
var c=connection.CreateTableAsync<LoginUserInfoDbModel>().Result;
var UserData = connection.Table<LoginUserInfoDbModel().ToListAsync().Result?.FirstOrDefault();
if(UserData != null)
{
MainPage= new DashBoardPage();
}
else
{
MainPage=new WelcomePages();
}
But this code is not working I am getting null reference Exception and some other exceptions, So do we have any alternative for this scenario or else can you suggest any modifications for this code ?

Related

Rg.Plugins.Popup error Rg.Plugins.Popup.Exceptions.RGPopupStackInvalidException: 'No Page in PopupStack'

i ran into this exception in my Xamarin Forms app that seems clear yet hard to resolve.
I created a kind of loader using the Rg.Plugins.Popup and i want to dismiss this loader when a user presses the back button while a web services is still running. But it throws this exception Rg.Plugins.Popup.Exceptions.RGPopupStackInvalidException: 'No Page in PopupStack' which means i am trying to remove a page that doesn't exist, and the app crashes. I have also followed the setup i saw here in the Docs. Below is my code;
private async void RemovePage()
{
var popPage = Rg.Plugins.Popup.Services.PopupNavigation.Instance.PopupStack;
if (!popPage.Any() || popPage.Count == 0 || popPage == null)
{
return;
}
else
{
var lastPage = popPage.Last();
if (lastPage.GetType() == typeof(LoadingPopup))
{
await Rg.Plugins.Popup.Services.PopupNavigation.Instance.RemovePageAsync(lastPage);
}
else
{
return;
}
}
}
Note: I am using the latest stable version 2.0.0.12 of Rg.Plugins.Popup and Xamarin.Forms 5.0.0.2012. Please what am i doing wrong here?

How to check if Firebase Facebook user exists - Unity

I want to check whether the user already exists in Firebase when they log in with Facebook or whether it's their first time. Firebase documentation just provides a function to login to facebook but doesn't mention if the user is new or not. A new user gets a new firebase user id, while an existing user just logs in.
By reading other similiar questions here- some people advised using AdditionalUserInfo.isNewUser for Javascript, but this function doesn't work for Unity code. Nothing about Unity here.
Basic code lines (after login to facebook)
Firebase.Auth.Credential credential =
Firebase.Auth.FacebookAuthProvider.GetCredential(accessToken);
auth.SignInWithCredentialAsync(credential).ContinueWith(task => {
if (task.IsCanceled) {
Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted) {
Debug.LogError("SignInWithCredentialAsync encountered an error: " +
task.Exception);
return;
}
Firebase.Auth.FirebaseUser newUser = task.Result;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
});
One solution that I was thinking about is to catch the exception - but couldn't find the exception code in their documentation - Firebase don't have a lot of info for Unity there
Here is a brief code that can help you.
public FirebaseAuth auth;
auth.FetchProvidersForEmailAsync(emailGotFromFacebook).ContinueWith((emailCheckingTask) =>
{
List<string> allProviders = ((IEnumerable<string>)emailCheckingTask.Result).ToList();
for (int i = 0; i < allProviders.Count; i++)
{
string provider = allProviders[i];
Debug.Log(provider);
}
});
You can check wheter it's the first login or if the user already exists using the following comparison: newUser.Metadata.CreationTimestamp == newUser.Metadata.LastSignInTimestamp
.. as shown below:
Firebase.Auth.FirebaseUser newUser = task.Result;
if (newUser.Metadata.CreationTimestamp == newUser.Metadata.LastSignInTimestamp) {
Debug.Log("User signed for the first time");
}
else {
Debug.Log("User already exists");
}

Facebook SDK on Unity Test Users returning empty data sets

I'm having an issue whereby I had previously had three test users, and by adding new users and using the same code, I could not get the user's data. Here is my code:
public void myScores (Action<IGraphResult> callback = null) {
FB.API ("/me/scores", HttpMethod.GET, delegate(IGraphResult result) {
Debug.Log("MyScoresCallback");
if (result.Error != null)
{
Debug.LogError(result.Error);
return;
}
Debug.Log (result.RawResult);
if (callback != null) {
callback (result);
}
});
}
From the Debug.Logs, for the three initial test users, this returns the users name and score object. For the new test user and my own access token, this returns an empty data set.
Isn't it supposed to work for all test users including myself?
Thank you!

MVC4 Forms Authentication Auto Login

So, what I am trying to accomplish is a basic "remember me" style action for users of my application.
I have completed writing everything so far, and it is working as expected most of the time. Occasionally though, the method to check for the persistent Forms Authentication ticket doesn't auto login, and I can't figure out why it is only happening occasionally.
To test my code, what I have done is start the debugger, manually kill my session cookie in chrome's dev tools, then reload the page. Stepping through the code, it enters into the auto login method as expected and proceeds to reset my session data. However, if I wait an inordinate amount of time, like 4 hours perhaps, and try the same thing it does not auto reset my session. (Assuming that i've left the debugger running for that amount of time).
EDIT: For clarity's sake, when this error is happening, I can open the dev tools and see that the authentication ticket is still available. It's just the code to reset my session is either not running, for erroring out somewhere. Due to the infrequency in which this is happening, it's hard to track down.
So, onto the code.
I'm calling the static void auto login method in the controller's constructor, and passing the httpcontext into the auto login method.
Controller
public class SiteController : Controller
{
public SiteController()
{
this.UserAutoLogin(System.Web.HttpContext.Current);
}
// GET: /Site/
public ActionResult Index()
{
ViewBag.CatNav = this.RenderNavCategories();
return View();
}
}
Auto Login Code
public static void UserAutoLogin(this Controller Controller, System.Web.HttpContext context)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(FormsAuthentication.FormsCookieName);
if (cookie != null)
{
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
if (ticket != null)
{
if (ticket.Name.Length > 0)
{
try
{
if (context.Session["UserName"] == null)
{
//get user from db
PersonRepository PersonRepo = new PersonRepository();
PersonModel Member = PersonRepo.GetUserUserName(ticket.Name);
if (Member.FirstName != null) //if this is null...then the cookie is wrong, so don't do shit
{
//Set the session parameters
context.Session["FirstName"] = Member.FirstName;
context.Session["LastName"] = Member.LastName;
context.Session["UserId"] = Member.Id;
context.Session["UserName"] = Member.Username;
context.Session["Email"] = Member.Email;
context.Session["IsUser"] = 1;
context.Session["Zip"] = Member.Zip;
FormsAuthentication.SignOut();
FormsAuthentication.SetAuthCookie(Member.Username, true);
}
}
}
catch (Exception ex)
{
// don't do anything for now - do something smart later :)
Console.WriteLine(ex.ToString());
}
}
}
}
}
Because when IIS is recycling the app, a new machine key is generated. The FormsAuthentication ticket is signed using that key so when the key changes the old ticket isn't recognized. You need to use a fixed machine key.
Edit: Removed link to key generator site (now defunct)

what is used in windows app on the place of Session?

i am new to windows programming, as we use Store user's details in Session when user successfully logged into a web application and check the session in master page every time, if it will null then redirect the user to login page. I want to do the same thing in Windows application, i have created a login form: the code is written below:
private void btnLogin_Click(object sender, EventArgs e)
{
clsLogin obj = new clsLogin();
DataTable dtLogin = obj.Login_Check(txtUserName.Text.Trim(), txtPassword.Text.Trim());
if (dtLogin.Rows.Count > 0)
{
if (dtLogin.Rows[0]["result"].ToString() == "3")
{
lblMessage.Text = "Password does not matched";
}
else
if (dtLogin.Rows[0]["result"].ToString() == "2")
{
lblMessage.Text = "User does not exists";
}
else
{
Staff.Home home = new Staff.Home();
this.Hide();
home.Show();
}
}
}
}
Now what i want to do is: store the user info some where and when user click on Log off then it will destroy that session and it will open the Login form.
i know it is a very silly question, as i am new to windows programming its tough for me, please help.
Apart from the obvious issues with the code:
Direct access to rows by index
Login being done in the event handler directly
You should have separate login service and data access service
I would:
Create a login service that maintains the current logged in user details and performs the authentication itself.
Create a data access service that the login service can call to access the datastore
Then in your event handler you just need to call:
if (loginService.Authenticate(username, password))
{
// Do your UI handling here
}
then the loginService will have a .CurrentUser property for example and you can go from there.
e.g.
public class LoginService
{
private User _currentUser;
public bool Authenticate(string username, string password)
{
if (_currentUser != null)
{
Logout();
}
else
{
var user = DataAccess.Get("users").SingleOrDefault(u => u.Username = username);
if (user == null)
{
throw new Exception("No user with that username found");
}
if (password == user.Password)
{
_currentUser = user;
return true;
}
else
{
return false;
}
}
}
public User CurrentUser
{
get { return _user; }
}
}
In a Web application it is supposed that there are multiple clients connected to the single server; you should use Session to distinguish between them and to pass data to each of them "there and back again". For a desktop application this problem does not exist at all - there is exactly one user and his data is all here: you do not need some special mechanism like Session for it.
This means that you may use a number of different approaches to pass data from your form. In your example it seems more logical to pass data to your "home" form directly, either through constructor
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home(userData);
this.Hide();
home.Show();
}
or through a property
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home();
home.UserData = userData;
this.Hide();
home.Show();
}
This is only an example, there are a lot alternatives - just think about this "single user, always on site" model.

Categories