user4857063
user4857063

Reputation:

keep user logged into xamarin.forms app unless log-out is clicked

I am using xamarin.forms for my app. It allows the user to log in via facebook. I have added a logout button in the app to simply navigate back to the login page but i noticed that when i exit my app without pressing the logout button, the app resumes at the login page( causing the user to keep entering their login details everytime they have to re-open the app). How can I keep the user logged in when they close and reopen the app? Any guidance on this will be appreciated..

App.cs (MainPage is my login page)

 public App()
        {
            InitializeComponent();
            MainPage = new NavigationPage(new MainPage());
        }

        public async static Task NavigateToSMS()
        {
            await App.Current.MainPage.Navigation.PushAsync(new SMS());
        }

        public static void NavigateToProfile()
        {
            App.Current.MainPage = (new InvalidLogin());
        }
        public static void NavigateToVerified()
        {
            App.Current.MainPage = (new Profile());
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app sleeps
        }

FacebookRender

[assembly: ExportRenderer(typeof(Login), typeof(LoyaltyWorx.Droid.FacebookRender))]
namespace LoyaltyWorx.Droid
{

    public class FacebookRender : PageRenderer
    {
        public FacebookRender()
        {

            String error;
            var activity = this.Context as Activity;

            var auth = new OAuth2Authenticator(
                clientId: "",
                scope: "email",
                authorizeUrl: new Uri("https://www.facebook.com/dialog/oauth/"),
                redirectUrl: new Uri("https://www.facebook.com/connect/login_success.html")
                );

            auth.Completed += async (sender, eventArgs) =>
                {
                    try
                    {
                        if (eventArgs.IsAuthenticated)
                        {
                            await AccountStore.Create().SaveAsync(eventArgs.Account, "FacebookProviderKey");

                            var accessToken = eventArgs.Account.Properties["access_token"].ToString();
                            var expiresIn = Convert.ToDouble(eventArgs.Account.Properties["expires_in"]);
                            var expiryDate = DateTime.Now + TimeSpan.FromSeconds(expiresIn);

                            var request = new OAuth2Request("GET", new Uri("https://graph.facebook.com/me?fields=email,first_name,last_name,gender,picture"), null, eventArgs.Account);
                            var response = await request.GetResponseAsync();
                            var obj = JObject.Parse(response.GetResponseText());

                            var id = obj["id"].ToString().Replace("\"", "");
                            var name = obj["first_name"].ToString().Replace("\"", "");
                            var surname = obj["last_name"].ToString().Replace("\"", "");
                            var gender = obj["gender"].ToString().Replace("\"", "");
                            var email = obj["email"].ToString().Replace("\"", "");

                            Customer.Customers cust = new Customer.Customers();
                            cust.Number = "";
                            cust.Name = name;
                            cust.Surname = surname;
                            cust.Address = "sample";
                            cust.Email = email;
                            cust.City = "DBN";
                            cust.Region = "KZN";
                            cust.Country = "SA";
                            cust.MobilePhone = " ";
                            cust.DOB = DateTime.Now;
                            cust.Phone = " ";
                            cust.Credentials = new Customer.Credentials();
                            cust.Credentials.Authenticated = true;
                            cust.Credentials.SecretKey = "73fnfdbjfdj";
                            cust.DeviceToken = GcmService.RegistrationID;


                            CustomerService service = new CustomerService();
                            Settings.Token = await service.AddCustomer(cust);
                            if (Settings.MobileNo == null || Settings.MobileNo == " ")
                            {
                                await App.NavigateToSMS();

                            }
                            else
                            {
                                App.NavigateToVerified();
                            }
                        }
                        else
                        {
                            App.NavigateToProfile();
                        }
                    }
                    catch(Exception ex)
                    {
                        error = ex.Message;
                    }
                };
            activity.StartActivity(auth.GetUI(activity));
        }





    }
}

The Page that comes up after user is signed in

namespace LoyaltyWorx
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class Profile : MasterDetailPage
    {
        public List<MasterPageItem> menuList { get; set; }
        public Profile()
        {
            InitializeComponent();
            this.lblMessage.Text = Settings.Name + " " + Settings.Surname;
            menuList = new List<MasterPageItem>();
            var page1 = new MasterPageItem() { Title = "Home", Icon = "home.png", TargetType = typeof(Page1) };
            var page2 = new MasterPageItem() { Title = "Cards", Icon = "card.png", TargetType = typeof(Cards) };
            var page3 = new MasterPageItem() { Title = "Transactions", Icon = "settings.png", TargetType = typeof(Transactions) };
            var page4 = new MasterPageItem() { Title = "My Profile", Icon = "profile.png", TargetType = typeof(UpdateProfile) };
            var page5 = new MasterPageItem() { Title = "Log out", Icon = "signout.png", TargetType = typeof(MainPage) };



            menuList.Add(page1);
            menuList.Add(page2);
            menuList.Add(page3);
            menuList.Add(page4);
            menuList.Add(page5);


            navigationDrawerList.ItemsSource = menuList;
            Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(Page1)));

        }
        private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var item = (MasterPageItem)e.SelectedItem;
            Type page = item.TargetType;

            Detail = new NavigationPage((Page)Activator.CreateInstance(page));
            IsPresented = false;
        }

    }
}

Settings Class: Stores logged in user's details

 public static class Settings
    {
        public static string Token;
        public static int CustId;
        public static string Name;
        public static string Surname;
        public static string Email;
        public static string MobileNo;
        public static string PhoneNo;


    }

App.cs - Update

public App()
        {
            App.Current.Properties["UserDetail"] = Settings.Token;
            InitializeComponent();
            var isLoggedIn = Current.Properties.ContainsKey("UserDetail");
            if (!isLoggedIn)
            {
                MainPage = new NavigationPage(new MainPage());
            }
            else
            {
                App.Current.MainPage = (new Profile());
            }

        }

Upvotes: 0

Views: 7383

Answers (2)

user4857063
user4857063

Reputation:

I solved this issue by using Settings Plugin. Works perfectly!

Upvotes: 0

MilanG
MilanG

Reputation: 2604

On every app launch you are loading the MainPage. You have to load the first page conditionally.

Xamarin.Forms implements Application.Current.Properties which stores the key value data in the local storage of the app.

On Login:

On Successful login, Store "True" value in the application's local storage in some key like IsLoggedIn as follows:

Application.Current.Properties ["IsLoggedIn"] = Boolean.TrueString;

On App Launch (App.cs)

public App()
{
    InitializeComponent();
    bool isLoggedIn = Current.Properties.ContainsKey("IsLoggedIn") ? Convert.ToBoolean(Current.Properties["IsLoggedIn"]) : false;
    if (!isLoggedIn)
    {
        //Load if Not Logged In
        MainPage = new NavigationPage(new MainPage());
    }
    else
    {
        //Load if Logged In
        MainPage = new NavigationPage(new YourPageToLoadIfUserIsLoggedIn());
    }
}

On Logout:

When you Logout, store the False value in the IsLoggedIn local storage key And clear the Navigation stack and Load the MainPage.

Application.Current.Properties ["IsLoggedIn"] = Boolean.FalseString;

Storing User Detail:

To store the Settings class object values, serialize it into Json (Nuget Package) string object and store it in some other key, say, UserDetail in Application.Current.Properties. When you need this data back, fetch from local storage and deserailize it and use it.

Store : App.Current.Properties["UserDetail"] = JsonConvert.SerializeObject(Settings); Retrieve : Settings userData = JsonConvert.DeserializeObject<Settings>(App.Current.Properti‌​es["UserDetail"]);

EDIT

Current.Properties.ContainsKey just checks if some key exists in the storage or not. It doesn't check if value exists. Before accessing any key-value, its necessary to check if that key exists or not.

Static class can't be serialized, so you need to create a Singleton instance of that class and then access that singleton instance to serialize.

Hope this will help!!.

Upvotes: 10

Related Questions