Xamarin forms with firebase user registration error - c#

i am developing an app using xamarin forms and firebase authentication
with xamarin.firebase.auth and xamarin.firebase.core
when i want to create a new user the code works fine but it gives me the exception
Java.Lang.IllegalStateException: 'Task is not yet complete'
when i trace the code line by line every thing works just fine and i get no errors but when running the app after creating user it gives me the exception.
this is my code:
inerface in pcl:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace XamarinFirebaseAuth
{
public interface IAuth
{
Task<string> LoginWithEmailPassword(string email, string password);
bool SignUpWithEmailPassword(string email, string password);
}
}
android implementation:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foundation;
using UIKit;
using XamarinFirebaseAuth;
using XamarinFirebaseAuth.iOS;
using Firebase.Auth;
using System.Threading.Tasks;
using Xamarin.Forms;
[assembly: Dependency(typeof(AuthIOS))]
namespace XamarinFirebaseAuth.iOS
{
public class AuthIOS : IAuth
{
public async Task<string> LoginWithEmailPassword(string email, string password)
{
try
{
var user = await Auth.DefaultInstance.SignInWithPasswordAsync(email, password);
var token = user.User.GetIdTokenAsync();
return token.ToString();
}
catch(Exception e)
{
return "";
}
}
public bool SignUpWithEmailPassword(string email, string password)
{
try
{
var signUpTask = Auth.DefaultInstance.CreateUserAsync(email, password);
return true;
}
catch (Exception e)
{
throw;
//return false;
}
}
}
}
and this is my sign up page :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XamarinFirebaseAuth
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SignUpPage : ContentPage
{
IAuth auth;
public SignUpPage()
{
InitializeComponent();
auth = DependencyService.Get<IAuth>();
}
private async void btnRegister_Clicked(object sender, EventArgs e)
{
try
{
bool created = auth.SignUpWithEmailPassword(EmailInput.Text, PasswordInput.Text);
if (created)
{
await DisplayAlert("Success", "Your account created successfully", "OK");
await Navigation.PopAsync();
}
else
{
await DisplayAlert("Error", "Something went wrong. Try again later!", "OK");
}
}
catch
{
throw;
}
}
}
}

I think you should await the CreateUserAsync method to know whether the account is created successfully or not:
AuthDataResult signUpTask = await Auth.DefaultInstance.CreateUserAsync(email, password);
Then you can get the user info:
await signUpTask.User.GetIdTokenAsync();

Related

How to populate a text box with data from another .cs files' class

Hi im so sorry for the generic question i am really new to C#. I am using a previous colleagues code but im looking to populate a textbox on a form with the data from a class.
This is the code for the thing i want to reference
public string GetToken(string username, string password) {
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
I need to populate my text box with this.ExtractToken(response.Body). How do i do this?
Thanks a lot!
Code for main .cs file
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Configuration;
using System.IO;
namespace EbsWebServices
{
internal sealed class EbsAuthManager
{
private readonly string _url;
private readonly SvcUtility _svc = new SvcUtility();
public EbsAuthManager()
{
_url = "URL_HERE";
if(!_url.EndsWith("/"))
{
_url += "/";
}
_url += "Rest/Authentication";
}
public string GetToken(string username, string password)
{
var request = SvcRequest
.Get(_url)
.WithAuthentication(this.CreateHeader(username, password))
.ReturningXml();
var response = _svc.Send(request);
return this.ExtractToken(response.Body);
}
private string CreateHeader(string username, string password)
{
var credentials = String.Format("{0}:{1}", username, password);
var encoded = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));
return String.Format("Basic {0}", encoded);
}
private string ExtractToken (string xml)
{
var doc = new XmlDocument();
doc.LoadXml(xml);
var navigator = doc.DocumentElement.CreateNavigator();
var success = navigator
.SelectChildren("Success", string.Empty)
.Cast<XPathNavigator>()
.First();
var token = navigator
.SelectChildren("Token", string.Empty)
.Cast<XPathNavigator>()
.First();
return Convert.ToBoolean(success.InnerXml)
? token.InnerXml
: null;
}
}
}
Code for my form
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EbsWebServices;
namespace EBSGetTokenForm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}

GET, POST to a rest api

Hi i have a Api that i want to use to collect data from a backend that spits out json i need to get this via C# Application and it's http functionalities. My question is should i use a rest api and setup an async thread that downloads the data and then use the data as i want to from there or should i somehow use something close to a Web Api i have an authentication that is required to exist in a header. This has given me some hedaches because i keep on being split by what to use for what. I mean i need to do a Httprequest with a header. this i later on need to use for posting to another database. but the user of the program should not have to see the data itself. i have two examples that i have done but i don't know with what i should continue? this is my two examples in code...
Example 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
namespace Plugin
{
public enum HttpVerb
{
GET,
POST,
PUT,
DELETE
}
class Api
{
private HttpVerb HttpMethod { get; set; }
public Api()
{}
public string startDownload()
{
return (Download("sending token"));
}
private string Download(string token)
{
string strResponseValue = string.Empty;
string finnishedOutput = string.Empty;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("Url");
request.Headers.Add("Authorization", "Bearer " + token);
request.Method = HttpMethod.ToString();
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
strResponseValue = reader.ReadToEnd();
}
return strResponseValue;
}
catch (WebException e)
{
HttpWebResponse httpResponse = (HttpWebResponse)e.Response;
if ((int)httpResponse.StatusCode == 401)
{}
int errorCodeInt;
string errorCode;
errorCodeInt = (int)httpResponse.StatusCode;
errorCode = errorCodeInt.ToString();
return errorCode;
}
}
}
}
Example 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestAPi
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Api.InitializeClient("");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http;
namespace TestAPi
{
public class Api
{
private static HttpClient ApiClient { get; set;}
private string url { get; set;}
public static void InitializeClient(string token)
{
ApiClient = new HttpClient();
ApiClient.BaseAddress = new Uri("your url");
ApiClient.DefaultRequestHeaders.Accept.Clear();
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("Bearer Authentication"));
}
public async Task<Data> LoadData()
{
url = ApiClient.BaseAddress.ToString();
using (HttpResponseMessage response = await ApiClient.GetAsync(url))
{
if (response.IsSuccessStatusCode)
{
Data data = await response.Content.ReadAsAsync<data>();
return data;
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
}
}
}

error while accessing the microphones using in web view in xamarin forms?

I am displaying the groupword API in webview. The webview is not able to connect to my phones microphone and speaker how ever i allowed all permissions to the application.
async Task<bool> RequestPermission()
{
var status = PermissionStatus.Unknown;
status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Microphone);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Microphone))
{
//await DisplayAlert("Need Microphone", "We need microphone permission", "OK");
return false;
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Microphone);
status = results[Permission.Microphone];
return true;
}
if (status == PermissionStatus.Granted)
{
return true;
}
return false;
}
Calling WebView
var Status = await RequestPermission();
if(Status)
{
await Navigation.PushAsync(new InAppBrowserXaml("https://www.groupworld.net/room/1/demo?hide_playback=true"));
}
else
{
await DisplayAlert("Need Microphone", "We need microphone permission", "OK");
return;
}
You need to grant the permission by using CustomRenderer
in your Android project .
using Android.App;
using Android.Content;
using Android.Net.Http;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Webkit;
using Android.Widget;
using xxx;
using xxx.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(CustomWebViewRenderer))]
namespace xxx.Droid
{
public class MyWebChromeClient : WebChromeClient
{
public override void OnPermissionRequest(PermissionRequest request)
{
base.OnPermissionRequest(request);
request.Grant(request.GetResources());
}
}
public class CustomWebViewRenderer : WebViewRenderer
{
public CustomWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
var customWebView = Element as Xamarin.Forms.WebView;
// Control.SetBackgroundColor (Android.Graphics.Color.Red);
Control.Settings.JavaScriptEnabled = true;
Control.SetWebChromeClient(new MyWebChromeClient());
}
}
}
}

why do I have this Rest Api uri error?

My problem
I have my Universal Windows Application and i want work with rest api.
I always get error CS 4032 in this :
httpResponseBody = await httpClient.GetStringAsync(requestUri);
Like you can't call that method when it is not async.
Whole code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using System.Net;
using Windows.Web.Http;
namespace UniversalCA
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
Send();
}
public string Send()
{
HttpClient httpClient = new HttpClient();
Uri requestUri = new Uri("http://restapic.azurewebsites.net/WebForm1.aspx?func=dd&hodn=WW");
HttpResponseMessage httpResponse = new HttpResponseMessage();
string httpResponseBody = "";
try
{
httpResponseBody = await httpClient.GetStringAsync(requestUri);
}
catch (Exception ex)
{
httpResponseBody = "Error: " + ex.HResult.ToString("X") + " Message: " + ex.Message;
}
string tt = httpResponseBody.Split('>')[1].Split('<')[0];
return httpResponseBody;
}
}
}
The problem is that you cannot use await keyword inside a not async function. Your Send function does not have async keyword in declaration. Adding async keyword will solve the problem
public async Task<string> Send()
Just To add to #Ruben Vardanyans answer.
simply:
add using System.Threading.Tasks;
add Wait() keyword on your Send(); call
public MainPage()
{
this.InitializeComponent();
Send().Wait();
}
and finally on your Send() method
add async Task<T>
public async Task<string> Send()
Please check out this answer for calling an asynchronous method inside a constructor. Call asynchronous method in constructor?
do not use await Send(); for calling the method you will have a compiler error.

ASP.NET WEB API Forms Authentication Error

I am trying to create a web api with forms based authentication. I want to login from a client and retrieve data from there. When I log in, user gets authenticated and can retrieve data by giving http request direct into adressbar like localhost:1393/api/Game. But when i try to get it from client I am getting a 401 (Unauthorized error). I have enabled CORS in server side. This is the controller to handle data
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.Web.Security;
using Cheeky_backend.Models;
using System.Web.Http.WebHost;
namespace Cheeky_backend.Controllers
{
public class Demo
{
public List<Teams> team { get; set; }
public List<Hole> hole { get; set; }
}
[Authorize]
public class GameController : ApiController
{
private Cheeky_backendContext db = new Cheeky_backendContext();
// GET api/Game
public IEnumerable<Hole> GetHoles()
{
return db.Holes.AsEnumerable();
}
}
}
This is the authenticating controler
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Security;
using System.Web.Http;
using Cheeky_backend.Models;
namespace Cheeky_backend.Controllers
{
public class UserController : ApiController
{
private Cheeky_backendContext db = new Cheeky_backendContext();
// GET api/Default1
// GET api/Default1/5
// PUT api/Default1/5
// POST api/Default1
public HttpResponseMessage CreateUser(User user)
{
if (ModelState.IsValid)
{
db.Users.Add(user);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, user);
// response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = user.ID }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
// DELETE api/Default1/5
public HttpResponseMessage Login(User user)
{
var userfound = from user2 in db.Users
where user.username == user2.username && user.password == user2.password
select user2;
if( userfound.Any())
{
FormsAuthentication.SetAuthCookie(user.username, true);
return Request.CreateResponse(HttpStatusCode.OK,user);
}
return Request.CreateResponse(HttpStatusCode.Unauthorized);
}
}
}
Source
In your Authentication Handler
Don't set the Principal on the Thread.CurrentPrinicipal any more.
Use the Principal on the HttpRequestContext.
Take a look at here

Categories