IllegalArgumentException:使用Firebase - 将匿名帐户转换为永久帐户

时间:2018-04-02 06:54:03

标签: java android firebase firebase-authentication

在我开始解决问题之前,请原谅我的英语不好:我来自德国,很长一段时间没有使用英语。

我使用Firebase开发了一个简单的社区应用,效果很好。但在某些设备上,应用程序此时崩溃了:

(PasswordDialog.java:163) AuthCredential authCredential = EmailAuthProvider.getCredential(" user@example.com"," password_generated_from_mysql_database");

有了这条消息: java.lang.IllegalArgumentException异常: ...... ...... PasswordDialog.setFirebaseLinkAndDismiss(PasswordDialog.java:163) ......

首先,用户输入他的数据。之后我生成" getUid"用" firebaseAuth.signIn匿名"将其保存在MySQL数据库中。请看一下:

private void signInFirebaseAnonymously() {
    if(firebaseAuth.getCurrentUser() == null) {
        firebaseAuth.signInAnonymously().addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {

                if (task.isSuccessful()) {
                    currentUser = firebaseAuth.getCurrentUser();
                    userDatabase = FirebaseDatabase.getInstance().getReference().child("userDatabase").child(firebaseAuth.getCurrentUser().getUid());

                    putFirebaseUid = currentUser.getUid();
                    //Log.e(TAG, "uID vorhanden:    currentUser:" + putFirebaseUid);
                    sharedEditor.putString("fbAuthID", currentUser.getUid());
                    sharedEditor.apply();
                    createProfil(putFirebaseUid);
                } 
            }
        });
    } else {
        currentUser = firebaseAuth.getCurrentUser();
        putFirebaseUid = currentUser.getUid();

        sharedEditor.putString("fbAuthID", firebaseAuth.getCurrentUser().getUid());
        sharedEditor.apply();
        createProfil(putFirebaseUid);
    }
}

如果成功通过密码对话框启动新意图,请查看她:

                    passwordDialog.show();
                    passwordDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialogInterface) {
                            if(LOGIN_S)
                            {
                                Intent startStart = new Intent(MainActivity.this, Start.class);
                                startActivity(startStart);
                                finish();
                            } else {

                                Toast.makeText(getApplication(), R.string.errorcode21, Toast.LENGTH_LONG).show();
                                sharedPreferences = getSharedPreferences(SP, 0);
                                sharedEditor = sharedPreferences.edit();
                                sharedEditor.clear();   //Clear
                                sharedEditor.apply();
                                finish();
                            }
                        }
                    });
                    passwordDialog.setCancelable(false);
                    passwordDialog.setCanceledOnTouchOutside(false);

将密码发送到MySQL数据库并加密回来。最后开始将匿名帐户转换为永久帐户,并在大约30%的案例中崩溃。请看一下:

private void setPasswordAndCreateFirebaseAccout(final String userID, final String password){

    AsyncTask<Integer,Void,Void> task = new AsyncTask<Integer, Void, Void>() {

        @Override
        protected Void doInBackground(Integer... integers) {

            OkHttpClient client = new OkHttpClient();
            RequestBody formBody = new FormBody.Builder()
                    .add("id", ""+sharedPreferences.getInt("currentUserID",0))
                    .add("password", password)
                    .build();

            Request request = new Request.Builder()
                    .url("https://xxxxxxxxxx.com/setPass.php")
                    .post(formBody)
                    .build();

            try {
                okhttp3.Response response = client.newCall(request).execute();
                JSONObject jsonObject = new JSONObject(response.body().string());

                if(jsonObject.getString("status").equals("success"))
                {
                    LogState = true;
                    setThisMail = jsonObject.getString("e");
                    setThisPass = jsonObject.getString("p");

                } else {
                    LogState = false;
                }

            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.getMessage();
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            //Convert an anonymous account to a permanent account
            setFirebaseLinkAndDismiss(setThisMail, setThisPass);
        }

    };
    task.execute();
}
private void setFirebaseLinkAndDismiss(final String fbMail, final String fbPass)
{
   /*here crashes the app: error line PasswordDialog.java:163 */
   AuthCredential authCredential = EmailAuthProvider.getCredential(fbMail, fbPass);


    firebaseAuth.getCurrentUser().linkWithCredential(authCredential)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        currentUser = task.getResult().getUser();

                        firebaseAuth.signInWithEmailAndPassword(fbMail, fbPass).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                            @Override
                            public void onComplete(@NonNull Task<AuthResult> task) {

                                if(task.isSuccessful()){
                                    sharedEditor = sharedPreferences.edit();
                                    sharedEditor.putBoolean("currentUserPasswort", true);
                                    sharedEditor.apply();

                                    LOGIN_S = true;
                                    dismiss();
                                } else {
                                    LOGIN_S = false;
                                    dismiss();
                                }
                            }
                        });
                    } else {
                        LOGIN_S = false;
                        dismiss();
                    }
                }
    });
}

我希望你理解我的问题。我能做什么? 真诚的问候

1 个答案:

答案 0 :(得分:0)

AsyncTask中包含的setPasswordAndCreateFirebaseAccout()中,当网络请求失败时,您将LogState设置为false。当发生这种情况时,似乎setThisEmailsetThisPass未定义,可能为null(发布的代码不显示它们在这种情况下具有的值)。在onPostExecute()中,在LogState调用之前没有setFirebaseLinkAndDismiss()的测试,因此在网络请求失败且电子邮件和密码无效时调用它。我怀疑这是异常的原因。

要调试此问题,请在setFirebaseLinkAndDismiss()的开头添加一个日志语句,该语句将输出fbMailfbPass的值。为安全起见,您还应添加有效值的检查,例如:不是null,具有所需的格式(电子邮件:xxxx@yyyy.zzz)和长度。此外,由于您已加密它们,请检查它们是否包含无效字符。