2

私はFirebaseを使ってアンドロイドでアプリケーションを開発しています。データベースがほとんど空であってもFirebaseのクエリは永遠に実行されます

私の経験では、ログイン、OnDataChangedなどのデータの取得など、すべての作業は、データベースがほとんど空であっても巨大な遅延で行われています。コードをデバッグしているときに、プログラムフローが実行され、Firebaseリスナを「スキップ」してから、プログラムがかなり後の状態になった後にのみ実行されることがわかります。これは、私が通常はメインスレッドでスリープ状態で解決しようとしている多くの競合状態につながりますが、それは私のアプリケーションをさらに遅くし、それを不安定にします。私はFireLogのAuthWithPasswordメソッドを呼び出しているUserLoginTaskを使用し、認証が成功すると、OnDataChangedメソッドを呼び出してデータベースからユーザーのデータを取得していますシングルトンモデルであるMyAppModelに格納します。あなたがそれを見て、何が間違っているのかを教えてもらえれば嬉しいです。ありがとう!

package com.biu.ap2.mysitter; 

import android.animation.Animator; 
import android.animation.AnimatorListenerAdapter; 
import android.annotation.TargetApi; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Build; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.support.v7.app.AppCompatActivity; 
import android.text.TextUtils; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.View; 
import android.view.inputmethod.EditorInfo; 
import android.widget.AutoCompleteTextView; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

import com.firebase.client.AuthData; 
import com.firebase.client.DataSnapshot; 
import com.firebase.client.Firebase; 
import com.firebase.client.FirebaseError; 
import com.firebase.client.ValueEventListener; 
import com.google.android.gms.appindexing.Action; 
import com.google.android.gms.appindexing.AppIndex; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.firebase.auth.AuthResult; 


public class LoginActivity extends ActionBarActivity { 
    private static final String[] DUMMY_CREDENTIALS = new String[]{ 
      "[email protected]:hello", "[email protected]:world", "[email protected]:a" 
    }; 
    private UserLoginTask mAuthTask = null; 
    private AutoCompleteTextView mEmailView; 
    private EditText mPasswordView; 
    private View mProgressView; 
    private Button mRegisterView; 
    private View mLoginFormView; 

    myAppModel model; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_login); 




     mEmailView = (AutoCompleteTextView) findViewById(R.id.email); 
     //populateAutoComplete(); 

     mPasswordView = (EditText) findViewById(R.id.password); 
     mRegisterView = (Button) findViewById(R.id.register); 


     mRegisterView.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent i = new Intent(LoginActivity.this, RegisterActivity.class); 
       LoginActivity.this.startActivity(i); 
      } 
     }); 


     mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { 
      @Override 
      public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { 
       if (id == R.id.login_btnLogin || id == EditorInfo.IME_NULL) { 
        attemptLogin(); 
        return true; 
       } 
       return false; 
      } 
     }); 

     Button mEmailSignInButton = (Button) findViewById(R.id.login_btnLogin); 
     mEmailSignInButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       attemptLogin(); 
      } 
     }); 

     mLoginFormView = findViewById(R.id.login_btnLogin); 
     mProgressView = findViewById(R.id.login_progress); 
     // ATTENTION: This was auto-generated to implement the App Indexing API. 
     // See https://g.co/AppIndexing/AndroidStudio for more information. 
     client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build(); 
    } 


    private void attemptLogin() { 
     if (mAuthTask != null) { 
      return; 
     } 


      showProgress(true); 
      mAuthTask = new UserLoginTask(email, password); 
      mAuthTask.execute((Void) null); 
     } 
    } 

    private boolean isEmailValid(String email) { 
     //TODO: Replace this with your own logic 
     // return email.contains("@"); 
     return true; 
    } 

    private boolean isPasswordValid(String password) { 
     //TODO: Replace this with your own logic 
     // return password.length() > 0; 
     return true; 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
    } 


    public class UserLoginTask extends AsyncTask<Void, Void, Boolean> { 

     private final String mEmail; 
     private final String mPassword; 
     boolean flag = false; 

     UserLoginTask(String email, String password) { 
      mEmail = email; 
      mPassword = password; 

     } 

     public void setFlag(boolean flag) { 
      this.flag = flag; 
     } 

     public boolean getFlag() { 
      return this.flag; 
     } 


     @Override 
     protected Boolean doInBackground(Void... params) { 
      // TODO: attempt authentication against a network service. 
      Firebase.setAndroidContext(LoginActivity.this); 
      final Firebase ref = new Firebase("https://mybabysit.firebaseio.com/"); 
      ref.authWithPassword(mEmail, mPassword, new Firebase.AuthResultHandler() { 
       @Override 
       public void onAuthenticated(AuthData authData) { 
        setFlag(true); 
        setUser(mEmail); 
       } 

       @Override 
       public void onAuthenticationError(FirebaseError firebaseError) { 
        Log.d("blah", firebaseError.getMessage()); 
        System.out.println(firebaseError.getMessage()); 
       } 
      }); 

      try { 
       // Simulate network access. 
       Thread.sleep(8000); 
      } catch (InterruptedException e) { 
       return false; 
      } 
      if (getFlag()) 
       return true; 
      return false; 
     } 

     @Override 
     protected void onPostExecute(final Boolean success) { 
      mAuthTask = null; 
      showProgress(false); 

      if (success) { 

       try { 
        // Simulate network access. 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 

       } 
       finish(); 
       Intent i = new Intent(LoginActivity.this, IntroductionActivity.class); 
       i.putExtra("email", mEmail); 
       LoginActivity.this.startActivity(i); 
      } else { 
       mPasswordView.setError(getString(R.string.failed)); 
       mPasswordView.requestFocus(); 
      } 
     } 

     @Override 
     protected void onCancelled() { 
      mAuthTask = null; 
      showProgress(false); 
     } 
    } 

    /** 
    * Shows the progress UI and hides the login form. 
    */ 
    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) 
    private void showProgress(final boolean show) { 
     // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow 
     // for very easy animations. If available, use these APIs to fade-in 
     // the progress spinner. 
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 
      int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); 

      mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
      mLoginFormView.animate().setDuration(shortAnimTime).alpha(
        show ? 0 : 1).setListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationEnd(Animator animation) { 
        mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
       } 
      }); 

      mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
      mProgressView.animate().setDuration(shortAnimTime).alpha(
        show ? 1 : 0).setListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationEnd(Animator animation) { 
        mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
       } 
      }); 
     } else { 
      // The ViewPropertyAnimator APIs are not available, so simply show 
      // and hide the relevant UI components. 
      mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); 
      mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); 
     } 
    } 


    public void setUser(final String email) { 
     model = model.getInstance(); 
     final String mEmail=email; 
     Firebase ref = new Firebase("https://mybabysit.firebaseio.com"); 
     Firebase userRef = ref.child("users"); 
     // Firebase uidref=ref.child("uid").child(ref.getAuth().getUid()); 
     // Attach an listener to read the data at our sitterPosts reference 
     userRef.addValueEventListener(new ValueEventListener() { 
      //ref.addValueEventListener(new ValueEventListener() { 
      @Override 
      public void onDataChange(DataSnapshot snapshot) { 
       for (DataSnapshot UserSnapshot : snapshot.getChildren()) { 
        User myUser = UserSnapshot.getValue(User.class); 
        if (mEmail.equals(myUser.getEmail())) 
         model.getInstance().setLoggedUser(myUser); 
       } 
      } 
      @Override 
      public void onCancelled(FirebaseError firebaseError) { 
       System.out.println("The read failed: " + firebaseError.getMessage()); 
      } 
     }); 
    } 
} 
//*/ 

更新****:遅い応答がOnAuthenticate内部の "SETUSER" 方法によるものであったようです。データベースからビットマップオブジェクトを受け取り、ビットマップを受け取るのに非常に時間がかかります。そこからそれを削除し、ビットマップを圧縮することで、クエリーが約5倍速くなりました.3秒間スリープすると作業が完了したようです。

ご回答いただきありがとうございます。

+1

Maybyこれによって遅延が発生しています。Thread.sleep(8000); –

+2

また、非同期タスクでFirebaseを設定する必要はありません。おそらくあなたはまだ持っている問題とは無関係です。 – C0D3LIC1OU5

+1

Firebase 2.5.xからのアップグレードを検討する(このガイドの概要に従う)(https://firebase.google.com/support/guides/firebase-android)。また、[ActionBarActivity](https://developer.android.com/reference/android/support/v7/app/ActionBarActivity.html)は廃止され、 'AppCompatActivity'に置き換えられました。 –

答えて

0

更新:応答が遅いのは、OnAuthenticate内の「SetUser」メソッドだと思われます。データベースからビットマップオブジェクトを受け取り、ビットマップを受け取るのに非常に時間がかかります。それをそこから取り除き、ビットマップを圧縮することで、クエリーが約5倍速くなり、わずか3秒の睡眠が今や仕事をするようになりました。

ご回答いただきありがとうございます。

関連する問題