0

RxJavaのアプローチを使用して、私のアプリケーションにFirebus用のGoogle SignInを統合しようとしています。しかし何らかの理由でそれは遅いです。私はこの問題を解決するために私のアプローチで入れ子Observablesを使用しています。誰かがこの問題のより効率的な解決法を提案することができますか? GoogleのサインインボタンをRxjava2 + Google SignIn In Firebase

この私のコードへのステップバイステップのチュートリアルです

ユーザーがクリック

@OnClick(R.id.googleButton) 
    void googleSignUpButtonClicked() { 
     // Configure sign-in to request the user's ID, email address, and basic 
     // profile. ID and basic profile are included in DEFAULT_SIGN_IN. 
     GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
       .requestIdToken(getString(R.string.default_web_client_id)) 
       .requestEmail() 
       .build(); 

     // Build a GoogleApiClient with access to the Google Sign-In API and the 
     // options specified by gso. 
     mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) 
       .enableAutoManage(getActivity(), new GoogleApiClient.OnConnectionFailedListener() { 
        @Override 
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 

        } 
       } /* OnConnectionFailedListener */) 
       .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 
       .build(); 

     Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 
     startActivityForResult(signInIntent, RC_SIGN_IN); 
    } 

上記は、興味のある方のために、hereから単純なコピーペーストしました。 はその後onActivityResult()に私が「サインイン」を行い、私の関数を呼び出す:

@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 
     // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...); 
     if (requestCode == RC_SIGN_IN) { 
      GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 
      if (result.isSuccess()) { 
       // Google Sign In was successful, authenticate with Firebase 
       GoogleSignInAccount account = result.getSignInAccount(); 
       firebaseAuthWithGoogle(account); 
      } else { 
       // Google Sign In failed, update UI appropriately 
       // ... 
      } 
     } 
    } 

再びその単純なコピー&ペーストhereから。 firebaseAuthWithGoogle()Observable Sign'sているユーザで

し、このObservableに取り付けObserverは、ユーザは自分firebaseに存在するかどうチェックする別の観察を作成します。

private void firebaseAuthWithGoogle(GoogleSignInAccount acct) { 
     Log.d(TAG, "firebaseAuthWithGoogle:" + acct.getId()); 

     AuthCredential credential = GoogleAuthProvider.getCredential(acct.getIdToken(), null); 

     authenticateWithCredential = new DisposableObserver<AuthResult>() { 
      private DatabaseReference databaseReference; 
      private FirebaseUser firebaseUser; 

      @Override 
      public void onNext(AuthResult authResult) { 
       databaseReference = FirebaseDatabase.getInstance().getReference(); 
       firebaseUser = authResult.getUser(); 
      } 

      @Override 
      public void onError(Throwable e) { 
       Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onComplete() { 
       //checkUserExists.dispose(); 
       checkIfUserExists(databaseReference, firebaseUser); 
      } 
     }; 

     FirebaseAuthorization.observableSignInWithCredential(mAuth, credential) 
       .observeOn(Schedulers.io()) 
       .subscribeOn(AndroidSchedulers.mainThread()) 
       .subscribe(authenticateWithCredential); 
    } 

ユーザーが存在するかどうかを確認します。

public void checkIfUserExists(DatabaseReference databaseReference, FirebaseUser firebaseUser) { 
     checkUserExists = new DisposableObserver<DataSnapshot>() { 

      @Override 
      public void onNext(DataSnapshot dataSnapshot) { 
       if (dataSnapshot.exists()) { 
        SharedPreferences pref = getActivity().getSharedPreferences("GoogleFacebook", MODE_PRIVATE); 
        SharedPreferences.Editor editor = pref.edit(); 
        editor.putString("username", dataSnapshot.toString()); 
        editor.apply(); 
       } else { 
        enterUsernameDialog = new MaterialDialog.Builder(getActivity()) 
          .title("Almost There!") 
          .content("Give us an Awesome Username to Identify Yourself") 
          .inputType(InputType.TYPE_CLASS_TEXT | 
            InputType.TYPE_TEXT_VARIATION_PERSON_NAME) 
          .positiveText("Submit!") 
          .inputRange(4, 16) 
          .canceledOnTouchOutside(false) 
          .alwaysCallInputCallback() // this forces the callback to be invoked with every input change 
          .input("Username", "", new MaterialDialog.InputCallback() { 
           @Override 
           public void onInput(@NonNull MaterialDialog dialog, CharSequence input) { 
            if (input.toString().length() > 3 && input.toString().length() < 16) { 
             dialog.getActionButton(DialogAction.POSITIVE).setEnabled(true); 
            } 
           } 
          }).onPositive(new MaterialDialog.SingleButtonCallback() { 
           @Override 
           public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { 
            //showIndeterminateProgressDialog(false); 
            Toast.makeText(getActivity(), dialog.getInputEditText().getText().toString(), Toast.LENGTH_SHORT).show(); 
           } 
          }).autoDismiss(false).show(); 
       } 
      } 

      @Override 
      public void onError(Throwable e) { 
       Toast.makeText(getActivity(), "I do Exist: Error", Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onComplete() { 
       Toast.makeText(getActivity(), "I do Exist: Complete", Toast.LENGTH_SHORT).show(); 
      } 
     }; 
     observableSingleValueEvent(databaseReference.child("usersID").child(firebaseUser.getUid())) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribeOn(Schedulers.io()) 
       .subscribe(checkUserExists); 
    } 

まず、これは何らかの理由で遅すぎます。次に、MaterialDialog enterUsernameDialogが表示される前に、「私はExist:Complete」というトーストが呼び出されます。

誰かが私のやり方よりも良いアプローチを記述できますか? :)

答えて

0

UPDATE:2017年1月2日

をトピックに関する研究のトン後、私は最終的にそれを働かせました。 Observablesのネストされた混乱の代わりに、operatorsの1つをRxJavaからconcatMapという名前で使用しました。あなたが望むなら、あなたはそれを見ることができます。私はあなたの理解を助けるために、以下のコードを提示します。

FirebaseAuthorization.observableSignInWithCredential(mAuth, credential) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribeOn(Schedulers.io()) 
     .concatMap(new Function<AuthResult, Observable<DataSnapshot>>() { 
    @Override 
    public Observable<DataSnapshot> apply(AuthResult authResult) throws Exception { 
     databaseReference = FirebaseDatabase.getInstance().getReference(); 
     firebaseUser = authResult.getUser(); 
     progressDialog.setContent("Transferring Your User Data From Google To My App!"); 
     return observableSingleValueEvent(databaseReference.child("usersID").child(firebaseUser.getUid())); 
    } 
}).subscribe(checkUserExists); 

私はちょうどcheckUserExistsと呼ばれる1 Observer、その結果、ここにconcatMap()を使用して私の質問に上記のネストされた観測を吸収合併。この方法では、オブザーバはauthenticateWithCredentialにはありません。これは完了までに約1秒もかからず(テスト済み)、上記のアプローチよりもはるかに高速です。

誰かがこの問題に対するより良いアプローチをしている場合。共有してください:)

関連する問題