【问题标题】:Switching Activity to firebase- app shuts down将 Activity 切换到 firebase- 应用程序关闭
【发布时间】:2016-03-07 14:22:11
【问题描述】:

当用户单击 MainActivity 中的链接时,我在切换活动时遇到问题,应用程序将关闭,我不确定我是否对项目结构或正确声明类和扩展有问题。

基本上,我所做的是尝试将网站上提供的 Firebase 示例项目实施到我的应用程序中的一个活动中,以便有一种方法让会员登录,我删除了提供的初始代码 here 和在我的第二个活动窗口中实现它,链接中的代码用于 MainActivity,我希望它是 LoginFragment(只有一个名称)不使用片段。

因此,在最小化代码(删除 google、facebook 等)选项后,我最终得到了这个:

package net.we4x4.we4x4;

import android.app.AlertDialog;
import android.app.Application;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.firebase.client.AuthData;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;

import java.util.HashMap;
import java.util.Map;

 public class LoginFragment extends AppCompatActivity{

    private static final String TAG = MainActivity.class.getSimpleName();

    /* *************************************
     *              GENERAL                *
     ***************************************/
/* TextView that is used to display information about the logged in user */
    private TextView mLoggedInStatusTextView;

    /* A dialog that is presented until the Firebase authentication finished. */
    private ProgressDialog mAuthProgressDialog;

    /* A reference to the Firebase */
    private Firebase mFirebaseRef;

    /* Data from the authenticated user */
    private AuthData mAuthData;

    /* Listener for Firebase session changes */
    private Firebase.AuthStateListener mAuthStateListener;

    /* *************************************
     *              PASSWORD               *
     ***************************************/
    private Button mPasswordLoginButton;

    /* *************************************
     *            ANONYMOUSLY              *
     ***************************************/
    private Button mAnonymousLoginButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    /* Load the view and display it */
        setContentView(R.layout.activity_main);

    /* *************************************
     *               PASSWORD              *
     ***************************************/
        mPasswordLoginButton = (Button) findViewById(R.id.login_with_password);
        mPasswordLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginWithPassword();
            }
        });

    /* *************************************
     *              ANONYMOUSLY            *
     ***************************************/
    /* Load and setup the anonymous login button */
        mAnonymousLoginButton = (Button) findViewById(R.id.login_anonymously);
        mAnonymousLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginAnonymously();
            }
        });

    /* *************************************
     *               GENERAL               *
     ***************************************/
        mLoggedInStatusTextView = (TextView) findViewById(R.id.login_status);

    /* Create the Firebase ref that is used for all authentication with Firebase */
        mFirebaseRef = new Firebase(getResources().getString(R.string.firebase_url));

    /* Setup the progress dialog that is displayed later when authenticating with Firebase */
        mAuthProgressDialog = new ProgressDialog(this);
        mAuthProgressDialog.setTitle("Loading");
        mAuthProgressDialog.setMessage("Authenticating with Firebase...");
        mAuthProgressDialog.setCancelable(false);
        mAuthProgressDialog.show();

        mAuthStateListener = new Firebase.AuthStateListener() {
            @Override
            public void onAuthStateChanged(AuthData authData) {
                mAuthProgressDialog.hide();
                setAuthenticatedUser(authData);
            }
        };
    /* Check if the user is authenticated with Firebase already. If this is the case we can set the authenticated
     * user and hide hide any login buttons */
        mFirebaseRef.addAuthStateListener(mAuthStateListener);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();


        // if changing configurations, stop tracking firebase session.
        mFirebaseRef.removeAuthStateListener(mAuthStateListener);
    }

    /**
     * This method fires when any startActivityForResult finishes. The requestCode maps to
     * the value passed into startActivityForResult.
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Map<String, String> options = new HashMap<String, String>();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    /* If a user is currently authenticated, display a logout menu */
        if (this.mAuthData != null) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_logout) {
            logout();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * Unauthenticate from Firebase and from providers where necessary.
     */
    private void logout() {
        if (this.mAuthData != null) {
        /* logout of Firebase */
            mFirebaseRef.unauth();
            }
        /* Update authenticated user and show login buttons */
            setAuthenticatedUser(null);
        }


    /**
     * This method will attempt to authenticate a user to firebase given an oauth_token (and other
     * necessary parameters depending on the provider)
     */
    private void authWithFirebase(final String provider, Map<String, String> options) {
        if (options.containsKey("error")) {
            showErrorDialog(options.get("error"));
        } else {
            mAuthProgressDialog.show();
            if (provider.equals("twitter")) {
                // if the provider is twitter, we pust pass in additional options, so use the options endpoint
                mFirebaseRef.authWithOAuthToken(provider, options, new AuthResultHandler(provider));
            } else {
                // if the provider is not twitter, we just need to pass in the oauth_token
                mFirebaseRef.authWithOAuthToken(provider, options.get("oauth_token"), new AuthResultHandler(provider));
            }
        }
    }

    /**
     * Once a user is logged in, take the mAuthData provided from Firebase and "use" it.
     */
    private void setAuthenticatedUser(AuthData authData) {
        if (authData != null) {
        /* Hide all the login buttons */
            mPasswordLoginButton.setVisibility(View.GONE);
            mAnonymousLoginButton.setVisibility(View.GONE);
            mLoggedInStatusTextView.setVisibility(View.VISIBLE);
        /* show a provider specific status text */
            String name = null;
            if (authData.getProvider().equals("facebook")
                    || authData.getProvider().equals("google")
                    || authData.getProvider().equals("twitter")) {
                name = (String) authData.getProviderData().get("displayName");
            } else if (authData.getProvider().equals("anonymous")
                    || authData.getProvider().equals("password")) {
                name = authData.getUid();
            } else {
                Log.e(TAG, "Invalid provider: " + authData.getProvider());
            }
            if (name != null) {
                mLoggedInStatusTextView.setText("Logged in as " + name + " (" + authData.getProvider() + ")");
            }
        } else {
        /* No authenticated user show all the login buttons */
            mPasswordLoginButton.setVisibility(View.VISIBLE);
            mAnonymousLoginButton.setVisibility(View.VISIBLE);
            mLoggedInStatusTextView.setVisibility(View.GONE);
        }
        this.mAuthData = authData;
    /* invalidate options menu to hide/show the logout button */
        supportInvalidateOptionsMenu();
    }



    /**
     * Show errors to users
     */
    private void showErrorDialog(String message) {
        new AlertDialog.Builder(this)
                .setTitle("Error")
                .setMessage(message)
                .setPositiveButton(android.R.string.ok, null)
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }

    /**
     * Utility class for authentication results
     */
    private class AuthResultHandler implements Firebase.AuthResultHandler {

        private final String provider;

        public AuthResultHandler(String provider) {
            this.provider = provider;
        }

        @Override
        public void onAuthenticated(AuthData authData) {
            mAuthProgressDialog.hide();
            Log.i(TAG, provider + " auth successful");
            setAuthenticatedUser(authData);
        }

        @Override
        public void onAuthenticationError(FirebaseError firebaseError) {
            mAuthProgressDialog.hide();
            showErrorDialog(firebaseError.toString());
        }
    }

    /* ************************************
     *              PASSWORD              *
     **************************************
     */
    public void loginWithPassword() {
        mAuthProgressDialog.show();
        mFirebaseRef.authWithPassword("test@firebaseuser.com", "test1234", new AuthResultHandler("password"));
    }

    /* ************************************
     *             ANONYMOUSLY            *
     **************************************
     */
    private void loginAnonymously() {
        mAuthProgressDialog.show();
        mFirebaseRef.authAnonymously(new AuthResultHandler("anonymous"));
    }



public void switchToRegister(View v) {
    Intent Register = new Intent(this, Register.class);
    startActivity(Register);
}

}

正如你们所看到的,我将该类声明为公共类并扩展了 AppCompatActivity(不确定我必须扩展什么,刚刚从另一个教程中了解到)我还尝试从 Application 扩展它,我认为它可以工作,但是后来列出的代码中出现了各种错误:

在宣言中:

 <?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
    <activity
        android:name="net.we4x4.we4x4.MainActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".LoginFragment">
    </activity>

    <activity android:name=".Register">
    </activity>

    <!-- ATTENTION: This was auto-generated to add Google Play services to your project for
         App Indexing.  See https://g.co/AppIndexing/AndroidStudio for more information. -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
</application>

在 .LoginFragment 下的第 27 行中,它说它不能分配给 android.app.activity ?

然后在代码本身 LoginFragment :

我得到了这些我无法解决的错误: 第 58 行 - setContentView 无法解决此方法? setContentView(R.layout.fragment_login);

第 63 行 findViewById 也无法解析此方法?

         mPasswordLoginButton = (Button) findViewById(R.id.login_with_password);

相同的匿名选项第 75 行 mAnonymousLoginButton = (Button) findViewById(R.id.login_anonymously);

第 86 行 findViewById 有同样的问题吗? mLoggedInStatusTextView = (TextView) findViewById(R.id.login_status);

显然,如果我想扩展应用程序,我需要创建 findViewById 方法,但我没有继续这样做,因为我不知道我是否应该从应用程序扩展,考虑到当我在代码中没有收到任何这些错误时从 MainActivity 或 AppCompatActivity 扩展

我在第 114 行也无法解决此方法 super.onDestroy();

还有其他几个......?

所以我不确定如何解决这个问题?我应该扩展 Application 并解决这些错误(以及如何解决这些错误)还是保持 MainActivity 或 AppCompatActivity 的扩展?代码中不包含错误但无法正常切换活动:

我的 MainActivity 是:

 package net.we4x4.we4x4;

import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
 import android.support.v7.app.AppCompatActivity;
 import android.view.View;
 import android.widget.MediaController;
 import android.widget.VideoView;

 import com.firebase.client.Firebase;

 public class MainActivity extends AppCompatActivity {
public static final String VID_URL = "http://res.cloudinary.com/wi4x4/video/upload/v1457270321/bolivia_njb6r0.mp4";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if (savedInstanceState == null) {
        Firebase.setAndroidContext(this);


    VideoView vid = (VideoView)findViewById(R. id.VidClip);
    Uri video = Uri.parse(VID_URL);
    vid.setMediaController(new MediaController(this));
    vid.setVideoURI(video);
    vid.requestFocus();


}
 }


public void switchToLoginFragment(View v) {
    Intent LoginFragment = new Intent(this, LoginFragment.class);
    startActivity(LoginFragment);
}
public void switchToRegister(View v) {
    Intent Register = new Intent(this, Register.class);
    startActivity(Register);
}

}

错误日志是:

 6:16:51 PM AssertionError: Wrong element range PsiJavaFile:LoginFragment.java; committed=true

安卓显示器:

 03-07 18:19:52.512 21730-21730/net.we4x4.we4x4 E/AndroidRuntime: FATAL EXCEPTION: main
                                                             Process: net.we4x4.we4x4, PID: 21730
                                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{net.we4x4.we4x4/net.we4x4.we4x4.LoginFragment}: java.lang.IllegalStateException: For a custom firebase host you must first set your authentication server before using authentication features!
                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2429)
                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
                                                                 at android.app.ActivityThread.access$800(ActivityThread.java:166)
                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                 at android.os.Looper.loop(Looper.java:136)
                                                                 at android.app.ActivityThread.main(ActivityThread.java:5584)
                                                                 at java.lang.reflect.Method.invokeNative(Native Method)
                                                                 at java.lang.reflect.Method.invoke(Method.java:515)
                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
                                                                 at dalvik.system.NativeStart.main(Native Method)
                                                              Caused by: java.lang.IllegalStateException: For a custom firebase host you must first set your authentication server before using authentication features!
                                                                 at com.firebase.client.authentication.AuthenticationManager.checkServerSettings(AuthenticationManager.java:221)
                                                                 at com.firebase.client.authentication.AuthenticationManager.addAuthStateListener(AuthenticationManager.java:625)
                                                                 at com.firebase.client.Firebase.addAuthStateListener(Firebase.java:555)
                                                                 at net.we4x4.we4x4.LoginFragment.onCreate(LoginFragment.java:107)
                                                                 at android.app.Activity.performCreate(Activity.java:5447)
                                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393)
                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) 
                                                                 at android.app.ActivityThread.access$800(ActivityThread.java:166) 
                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283) 
                                                                 at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                 at android.os.Looper.loop(Looper.java:136) 
                                                                 at android.app.ActivityThread.main(ActivityThread.java:5584) 
                                                                 at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                 at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) 
                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) 
                                                                 at dalvik.system.NativeStart.main(Native Method) 

【问题讨论】:

  • Stack Overflow 是一个糟糕的调试器。这个问题有方式太多的信息来回答它。我在下面回答了一个问题,但其余的:设置一个*minimal, complete example 来重现一个问题。这需要您努力隔离问题,可能在您的应用程序之外。为什么这是有用和必要的都在this link中描述。
  • 我同意你的观点,是的,我需要提高我的调试技能才能更准确地定位问题。好吧,我正在学习编码和开发。这些也是必须获得的技能,无论如何感谢您的建议,您至少可以就可能存在的问题添加建议。
  • 我在评论之前添加了一个答案。但我评论的重点是,很少有人会花时间浏览大量代码来为您隔离问题。学习调试很棒,如果你要在 Stack Overflow 上发布问题,学习隔离你的问题也很重要。

标签: android android-intent firebase


【解决方案1】:

这个例外:

java.lang.RuntimeException:无法启动活动 ComponentInfo{net.we4x4.we4x4/net.we4x4.we4x4.LoginFragment}:java.lang.IllegalStateException:对于自定义 firebase 主机,您必须先设置身份验证服务器,然后才能使用身份验证功能!

来自这一行:

mFirebaseRef = new Firebase(getResources().getString(R.string.firebase_url));

原因是firebase_url的形式不是https://yours.firebaseio.com

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 2013-08-11
    • 2016-07-25
    • 1970-01-01
    相关资源
    最近更新 更多