首页 > 解决方案 > 如何在 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";
            }
        }
    }
}

我点击了以下链接: https ://www.youtube.com/watch?v=NYMCrD9klA0

标签: c#androidxamarinfirebase-authentication

解决方案


另一个答案是指用于 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


推荐阅读