c# - 如何在 C# 中的 Xamarin android 应用程序中从 google firebase 进行身份验证后获取访问令牌?
问题描述
我正在使用 google firebase 身份验证在 c# 中的 Xamarin android 应用程序中工作。该代码在firebase上运行良好。它在登录时对用户进行身份验证并返回名称和电子邮件地址。但是我需要在 firebase 进行身份验证后的访问令牌,以便进一步使用 REST API。但是我无法获取访问令牌,我可以获得访问令牌吗?
代码如下:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Android.Gms.Auth.Api.SignIn;
using Android.Gms.Common.Apis;
using Android.Gms.Auth.Api;
using Firebase.Auth;
using Firebase;
using Android.Content;
using System;
using Android.Gms.Tasks;
using Java.Lang;
namespace loginGoogle
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity, IOnSuccessListener, IOnFailureListener, IOnCompleteListener
{
GoogleSignInOptions gso;
GoogleApiClient googleApiClient;
FirebaseAuth firebaseAuth;
Button signinButton;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
signinButton = (Button)FindViewById(Resource.Id.signInButton);
signinButton.Click += SigninButton_Click;
gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DefaultSignIn)
.RequestIdToken("759281956917-ib3rko81uvs4bvdf3g3p76f0dl7q8k64.apps.googleusercontent.com")
.RequestEmail()
.Build();
googleApiClient = new GoogleApiClient.Builder(this)
.AddApi(Auth.GOOGLE_SIGN_IN_API, gso).Build();
googleApiClient.Connect();
firebaseAuth = GetFirebaseAuth();
UpdateUI();
}
private FirebaseAuth GetFirebaseAuth()
{
var app = FirebaseApp.InitializeApp(this);
FirebaseAuth mAuth;
if (app == null)
{
var options = new FirebaseOptions.Builder()
.SetProjectId("login-bde5d")
.SetApplicationId("login-bde5d")
.SetApiKey("AIzaSyCql6njOSplLxy6Nd2tpNHNSeBxyOm6TQM")
.SetDatabaseUrl("https://login-bde5d.firebaseio.com")
.SetStorageBucket("login-bde5d.appspot.com")
.Build();
app = FirebaseApp.InitializeApp(this, options);
mAuth = FirebaseAuth.Instance;
}
else
{
mAuth = FirebaseAuth.Instance;
}
return mAuth;
}
private void SigninButton_Click(object sender, System.EventArgs e)
{
UpdateUI();
if (firebaseAuth.CurrentUser == null)
{
var intent = Auth.GoogleSignInApi.GetSignInIntent(googleApiClient);
StartActivityForResult(intent, 1);
}
else
{
firebaseAuth.SignOut();
UpdateUI();
}
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == 1)
{
GoogleSignInResult result = Auth.GoogleSignInApi.GetSignInResultFromIntent(data);
if (result.IsSuccess)
{
GoogleSignInAccount account = result.SignInAccount;
LoginWithFirebase(account);
}
}
}
private void LoginWithFirebase(GoogleSignInAccount account)
{
var credentials = GoogleAuthProvider.GetCredential(account.IdToken, null);
firebaseAuth.SignInWithCredential(credentials).AddOnSuccessListener(this)
.AddOnFailureListener(this).AddOnCompleteListener(this, this);
}
public void OnSuccess(Java.Lang.Object result)
{
TextView displayNameText = (TextView)FindViewById(Resource.Id.displaynameText);
TextView emailText = (TextView)FindViewById(Resource.Id.emailText);
displayNameText.Text = "Display Name: " + firebaseAuth.CurrentUser.DisplayName;
emailText.Text = "Email: " + firebaseAuth.CurrentUser.Email;
Toast.MakeText(this, "Login successful", ToastLength.Short).Show();
UpdateUI();
}
public void OnFailure(Java.Lang.Exception e)
{
Toast.MakeText(this, "Login Failed", ToastLength.Short).Show();
UpdateUI();
}
void UpdateUI()
{
if (firebaseAuth.CurrentUser != null)
{
signinButton.Text = "Sign Out";
}
else
{
signinButton.Text = "Sign In With Google";
}
}
public void OnComplete(Task task)
{
//throw new NotImplementedException();
if (task.IsSuccessful)
{
TextView photourlText = (TextView)FindViewById(Resource.Id.photoURLText);
photourlText.Text = "User successfully login with Photo URL: " + firebaseAuth.CurrentUser.PhotoUrl.Path;
}
else
{
TextView photourlText = (TextView)FindViewById(Resource.Id.photoURLText);
photourlText.Text = "problem in user login";
}
}
}
}
解决方案
另一个答案是指用于 Firebase 云消息传递/推送通知的令牌,而不是 OP 需要的用于 Firebase Auth 的令牌。
用户登录后,它会填充FirebaseAuth.Instance.CurrentUser
. 然后,您可以从登录用户那里获取令牌。
if (FirebaseAuth.Instance.CurrentUser != null)
{
var tokenRequest = await FirebaseAuth.Instance.CurrentUser.GetIdTokenAsync(true);
string token = tokenRequest.Token;
// Do whatever with token
}
笔记。当前的 Xamarin Firebase Auth 似乎存在一个错误,该错误会导致在对对象调用该GetIdTokenAsync()
方法时引发空引用异常。FirebaseUser
'Attempt to invoke virtual method 'com.google.android.gms.tasks.Task com.google.firebase.auth.FirebaseAuth.zza(com.google.firebase.auth.FirebaseUser, boolean)' on a null object reference'
该决议记录在这里 - https://github.com/xamarin/GooglePlayServicesComponents/issues/223
这是安装一个额外的 Nuget 包 - https://www.nuget.org/packages/Xamarin.Android.ManifestMerger/1.0.0-preview03
推荐阅读
- apache2 - 在多用户环境中使用 XDebug
- multithreading - 默认调度程序未并行化 Play 框架期货
- javascript - Bundler 2.0.2 和 Jekyll/Gulp 已安装,仍然收到“必须使用 Bundler 2 或更高版本”消息
- xamarin - 如何在 4k 屏幕上修复小型 android 模拟器
- audio - 如何在颤动中播放来自互联网的音频?
- python-3.x - 网页抓取到熊猫 DF
- java - Apache Tika 的进度报告?
- .net - 使用 .net 时,我无法在 Apache ignite 中部署服务
- vhdl - 运行 CORDIC IP VHDL
- java - 使用 Selenium Java 清除网络选项卡