I don’t have a lot of experience creating Java (.aar) plugins for Unity3d, but I am attempting to setup google authentication with firebase from such a plugin. To give an example of my problem, I begin by opening a unity android application, then I run the c# code below, and get a popup on my display to sign-in with google. I then choose the correct google account, then the google intent/activity disappears, then I receive no indication that “onActivityResult” has been called. No errors occur and I am unable to to do anything with the google account information that I chose.
In the image below, I click submit -> it opens the google sign-in activity in the next picture -> then it returns back to the submit screen (closing the google sign-in activity).
I think my issue is in this line:
activity.startActivityForResult(signInIntent, RC_SIGN_IN);
The “activity” in this case is a UnityPlayerActivity sent from the c# unity code below. I think this is making it so my code is looking for an “onActivityResult” method in the C# unity code rather than the java code. Any help would be greatly appreciated. Let me know if you need any other info or screenshots. Please call me out if I am being a moron.
Here is my code for calling the Google Signin Plugin From C# & Unity3d:
AndroidJNIHelper.debug = true; using (AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { activity_context = activityClass.GetStatic<AndroidJavaObject>("currentActivity"); } using (AndroidJavaClass pluginClass = new AndroidJavaClass("com.package.class")) { if (pluginClass != null) { GoogleSignInActivity = pluginClass.CallStatic<AndroidJavaObject>("instance"); GoogleSignInActivity.Call("SetContext", activity_context); GoogleSignInActivity.Call("StartGoogleLogin", activity_context); activity_context.Call("runOnUiThread", new AndroidJavaRunnable(() => { GoogleSignInActivity.Call("ShowMessage", "You signed in as " + display_name); })); } }
Here is the code for creating the Google SignIn Activity:
public void StartGoogleLogin(UnityPlayerActivity activity) { gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("some url") .requestEmail() .build(); mGoogleSignInClient = GoogleSignIn.getClient(activity, gso); Intent signInIntent = mGoogleSignInClient.getSignInIntent(); activity.startActivityForResult(signInIntent, RC_SIGN_IN); Log.d(TAG, "Activity Started; Waiting For Result"); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d(TAG, "Result Received!"); if (requestCode == RC_SIGN_IN) { Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); try { // Google Sign In was successful GoogleSignInAccount account = task.getResult(ApiException.class); someMethod(account); } catch (ApiException e) { // Google Sign In failed, update UI appropriately Log.d(TAG, "Google sign in failed", e); } setResult(RESULT_OK); } }
Thank you for your time.
Answer
Well, I solved my own problem of getting Google Authentication to work between the Android .aar plugin and Unity c#. Been working tirelessly and found some kickbutt resources.
First and foremost, I referenced the code written by a guy named cwgtech HERE.
I also went through all of his videos.
Instead of using UnitySendMessage, I was able to use a callback method similar to what CWGTech does to send a googleIdToken back to Unity and sign-in with Google into Firebase. I was also correct in thinking that my mistake was with the statement below:
activity.startActivityForResult(signInIntent, RC_SIGN_IN);
Instead of doing this, I followed CWGTech’s advice and removed “activity.” portion. I ran the startActivityForResult in a ResultCallback class that extends Activity. If you are still confused, dm me or comment on this post. Thanks!
Here is some of the code I used to send a callback string to Unity via a Java Proxy in written in C#. Information about writing a Java proxy can be found in the cwgtech information above. Writing the java proxy is extremely important if you want to get information to flow from Android activities to Unity C#. CWGTech explains the intricacies of java proxies way better than I could do justice.
public static final String LOGTAG = GoogleSignInActivity.TAG + "_OnResult"; public static GoogleSignInActivity.ShareStringCallback shareStringCallback; private static final int RC_SIGN_IN = 9001; private GoogleSignInClient mGoogleSignInClient; private GoogleSignInOptions gso; private CallbackManager mCallbackManager; public void myFinish(String myresult) { if (shareStringCallback != null) { shareStringCallback.onLoginComplete(myresult); } shareStringCallback = null; finish(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(LOGTAG, "onCreateBundle"); Intent intent = getIntent(); setContentView(R.layout.login_activity); findViewById(R.id.buttonFacebookLogin).setOnClickListener(this); findViewById(R.id.signInButton).setOnClickListener(this); findViewById(R.id.buttonAnonymousSignIn).setOnClickListener(this); } /* GOOGLE SIGN-IN CODE */ public Intent StartGoogleLogin() { /* Google Sign In Client Init Code Goes Here */ Intent signInIntent = mGoogleSignInClient.getSignInIntent(); return signInIntent; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { //Detects some type of result from an activity, in this case Google String id_result = "Send This To Unity"; myFinish(id_result); }
Here is a bit more code from a different java class file. The ‘Login’ method is called from Unity c#.
/* INTERFACES FOR CALLBACK FUNCTIONAILITY */ public interface ShareStringCallback { public void onLoginComplete(String result); } public void Login(final ShareStringCallback callback) { mainActivity.runOnUiThread(new Runnable() { @Override public void run() { try { Log.i(TAG,"Starting Authentication"); try { try { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setClass(mainActivity,OnResultCallback.class); OnResultCallback.shareStringCallback = callback; mainActivity.startActivity(shareIntent); } catch (Exception e) { e.printStackTrace(); Log.i(TAG,"error sharing intent: " + e); } } catch (Exception e) { e.printStackTrace(); Log.i(TAG,"Error getting Uri: " + e); } } catch (Exception e) { e.printStackTrace(); Log.i(TAG,"Error writing file: " + e); } } }); }