Xamarin Firebase Auth iOS

Viewed 632

I'm struggling to get Xamarin Firebase Auth on iOS return values coded correctly to process my success/fail logic working for both SignInWithEmailPasswordAsync(email, password) and the CreateUserAsync. I'm sure the problem is in my var user = and AuthDataResult signUpTask = code because the CreateUser and SignIn methods are actually working to add/login users to firebase because I can see them in the console... and if I manually register a user in firebase, the signed-in date is blank... and when I login them in through my iOS app, I see a date stamp appear there. If I register a new user, they appear in Firebase authentication console... all good there. It's just getting the return status from my AuthIOS.cs file back to the calling login and registration pages so I can process success or fail correctly. Any help or would be greatly appreciated. Here's my code:

project level - IAuth.cs

 using System.Threading.Tasks;

 namespace PelletPirate.Interfaces {
     public interface IAuth
     {
         Task<string> LoginWithEmailPassword(string email, string password);
         Task<string> SignUpWithEmailPassword(string email, string password);
     } }

project level - LoginPage.xaml.cs

using PelletPirate.Interfaces;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace PelletPirate.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    [DesignTimeVisible(true)]
    public partial class LoginPage : ContentPage
    {

        IAuth auth;

        public LoginPage()
        {
            InitializeComponent();
            auth = DependencyService.Get<IAuth>();
        }

        private async void BtnLogin_Clicked(object sender, EventArgs e)
        {
            string uid = await auth.LoginWithEmailPassword(Email.Text, Password.Text);
            await DisplayAlert("Do we have a user? ", uid, "Ok");
            if (uid != "")
            {
                ShowSuccess(uid);
            }
            else
            {
                ShowError();
            }
        }

        public async void ShowSuccess(string UID)
        {
            await DisplayAlert("Success!", UID, "OK");
            await Shell.Current.GoToAsync("//loggedin");
        }

        private async void ShowError()
        {
            await DisplayAlert("Authentication Failed", "E-mail or password are incorrect. Try again!", "OK");
        }

        private async void BtnRegister_Clicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync("//register");
        }

        private async void BtnGoogleLogin_Clicked(object sender, EventArgs e)
        {
            await DisplayAlert("Alert", "You need to delete this ADD button stuff", "OK");
        }

    }

}

project level - RegistrationPage.xaml.cs

namespace PelletPirate.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RegisterPage : ContentPage
    {

        IAuth auth;

        public RegisterPage()
        {
            InitializeComponent();
            auth = DependencyService.Get<IAuth>();
        }

        async void BtnRegister_Clicked(object sender, EventArgs e)
        {
            string uid = await auth.SignUpWithEmailPassword(Email.Text, Password.Text);
            await DisplayAlert("Uid: ", uid, "OK");
            if (uid != "")
            {
                await DisplayAlert("Success", "Welcome to Pellet Pirate!", "OK");
                await DisplayAlert("User", uid, "OK");
                await Shell.Current.GoToAsync("//main");
            }
            else
            {
                await DisplayAlert("Sign Up Failed", "Something went wrong. Try again!", "OK");
            }
        }

        private async void BtnCancel_Clicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync("//login");
        }

    }

}

iOS level - AuthIOS.cs

using Firebase.Auth;
using PelletPirate.Interfaces;
using PelletPirate.iOS;
using System;
using System.Threading.Tasks;
using Xamarin.Forms;

[assembly: Dependency(typeof(AuthIOS))]
namespace PelletPirate.iOS
{
    public class AuthIOS : IAuth
    {
        public async Task<string> LoginWithEmailPassword(string email, string password)
        {
            try
            {
                var user = await Auth.DefaultInstance.SignInWithPasswordAsync(email, password);
                return await user.User.GetIdTokenAsync();
            }
            catch (Exception)
            {
                return "";
            }
        }

        public async Task<string> SignUpWithEmailPassword(string email, string password)
        {
            try
            {
                AuthDataResult signUpTask = await Auth.DefaultInstance.CreateUserAsync(email, password);
                return signUpTask.User.Uid;
            }
            catch (Exception)
            {
                return "";
            }
        }
    }
}

** Thanks again for any guidance **

1 Answers

I figured it out. Just want to share for those that run into the same issue(s)! it was a couple of issues.

  1. Make sure your apple developer account is set up and you enter that into Visual Studio in Tools:Options:Xamarin:Apple Accounts.
  2. Make sure in Visual Studio menu, drop down Debug and click on the wrench at the bottom named "[your solution name].iOS". Make sure Automatic Provisioning is set and that you select a TEAM from the dropdown that comes from your apple developer set up you did in step #1.
  3. Finally, I modified my code to concentrate on getting and returning the users ID Token.

Here's the final code, adding the Android level too:

project level - IAuth.cs

using System.Threading.Tasks;

namespace PelletPirate.Interfaces
{
    public interface IAuth
    {
        Task<string> LoginWithEmailPassword(string email, string password);
        Task<string> SignUpWithEmailPassword(string email, string password);
    }
}

project level - LoginPage.xaml.cs

using PelletPirate.Interfaces;
using System;
using System.ComponentModel;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace PelletPirate.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    [DesignTimeVisible(true)]
    public partial class LoginPage : ContentPage
    {

        IAuth auth;

        public LoginPage()
        {
            InitializeComponent();
            auth = DependencyService.Get<IAuth>();
        }

        private async void BtnLogin_Clicked(object sender, EventArgs e)
        {
            var token = await auth.LoginWithEmailPassword(Email.Text, Password.Text);
            await DisplayAlert("Logged in: ", "Token: " + token, "OK");
                if (token != "")
            {
                ShowSuccess(token);
            }
            else
            {
                ShowError();
            }
        }

        public async void ShowSuccess(string Token)
        {
            await DisplayAlert("Success!", Token, "OK");
            await Shell.Current.GoToAsync("//loggedin");
        }

        private async void ShowError()
        {
            await DisplayAlert("Authentication Failed", "E-mail or password are incorrect. Try again!", "OK");
        }

        private async void BtnRegister_Clicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync("//register");
        }

        private async void BtnGoogleLogin_Clicked(object sender, EventArgs e)
        {
            await DisplayAlert("Alert", "You need to delete this ADD button stuff", "OK");
        }

    }

}

project level - RegistrationPage.xaml.cs

using PelletPirate.Interfaces;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace PelletPirate.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class RegisterPage : ContentPage
    {

        IAuth auth;

        public RegisterPage()
        {
            InitializeComponent();
            auth = DependencyService.Get<IAuth>();
        }

        async void BtnRegister_Clicked(object sender, EventArgs e)
        {
            var token = await auth.SignUpWithEmailPassword(Email.Text, Password.Text);
            await DisplayAlert("Token: ", token, "OK");
            if (token != "")
            {
                ShowSuccess(token);
            }
            else
            {
                ShowError();
            }
        }

        public async void ShowSuccess(string Token)
        {
            await DisplayAlert("Success!", Token, "OK");
            await Shell.Current.GoToAsync("//main");
        }

        private async void ShowError()
        {
            await DisplayAlert("Registration Failed", "Could not register to Pellet Pirate", "OK");
        }

        private async void BtnCancel_Clicked(object sender, EventArgs e)
        {
            await Shell.Current.GoToAsync("//login");
        }

    }

}

iOS level - AuthIOS.cs

using Firebase.Auth;
using PelletPirate.Interfaces;
using PelletPirate.iOS;
using System.Threading.Tasks;
using Xamarin.Forms;

[assembly: Dependency(typeof(AuthIOS))]
namespace PelletPirate.iOS
{
    class AuthIOS : IAuth
    {
        public async Task<string> LoginWithEmailPassword(string email, string password)
        {
            var authDataResult = await Auth.DefaultInstance.SignInWithPasswordAsync(email, password);
            System.Diagnostics.Debug.WriteLine("In AuthIOS right after var authDataResult " + authDataResult.User.Uid + " <<-- user uid here?");
            return await authDataResult.User.GetIdTokenAsync();
        }

        public async Task<string> SignUpWithEmailPassword(string email, string password)
        {
            var authDataResult = await Auth.DefaultInstance.CreateUserAsync(email, password);
            System.Diagnostics.Debug.WriteLine("In AuthIOS right after var authDataResult " + authDataResult.User.Uid + " <<-- user uid here?");
            return await authDataResult.User.GetIdTokenAsync();
        }

    }

}

Android level - AuthDroid.cs

using Firebase.Auth;
using PelletPirate.Droid;
using PelletPirate.Interfaces;
using System.Threading.Tasks;
using Xamarin.Forms;

[assembly: Dependency(typeof(AuthDroid))]
namespace PelletPirate.Droid
{
    public class AuthDroid : IAuth
    {

        public async Task<string> LoginWithEmailPassword(string email, string password)
        {
            var user = await FirebaseAuth.Instance.SignInWithEmailAndPasswordAsync(email, password);
            var token = await user.User.GetIdTokenAsync(false);
            return token.Token;
        }

        public async Task<string> SignUpWithEmailPassword(string email, string password)
        {
            var user = await FirebaseAuth.Instance.CreateUserWithEmailAndPasswordAsync(email, password);
            var token = await user.User.GetIdTokenAsync(false);
            return token.Token;
        }

    }
}

E N J O Y

Related