dataSnapshot 函数不起作用 - 函数调用时应用程序崩溃

Posted

技术标签:

【中文标题】dataSnapshot 函数不起作用 - 函数调用时应用程序崩溃【英文标题】:dataSnapshot function not working - App crashing when function call 【发布时间】:2020-11-08 04:09:22 【问题描述】:

我正在尝试使用存储我的用户名和密码的 firebase 实时数据库登录。当我输入错误的用户名时,我得到了错误。但是当我输入正确的凭据并点击登录时,应用程序崩溃了。不知道哪里做错了,求大神帮忙解决。非常感谢。

    firebase 数据库的屏幕截图

enter image description here

    android XML

     <ImageView
         android:id="@+id/login_img"
         android:layout_
         android:layout_
         android:layout_gravity="center"
         android:contentDescription="@string/login_img"
         android:src="@drawable/login" />
    
     <TextView
         android:id="@+id/h_login"
         android:layout_
         android:layout_
         android:text="Hello there, welcome back"
         android:textAllCaps="true"
         android:textColor="@color/colorPrimary"
         android:textSize="32sp"
         android:textStyle="bold"
         app:fontFamily="@font/roboto_bold" />
    
     <TextView
         android:layout_
         android:layout_
         android:text="Login to continue"
         android:textColor="@color/colorPrimaryMid"
         android:textSize="24sp"
         android:layout_marginTop="5dp"
         android:layout_marginBottom="10dp"/>
    
     <com.google.android.material.textfield.TextInputLayout
         android:id="@+id/username"
         style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
         android:layout_
         android:layout_
         android:hint="Username"
         android:layout_marginBottom="10dp">
    
         <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/edtUsername"
             android:layout_
             android:layout_ />
    
     </com.google.android.material.textfield.TextInputLayout>
    
     <com.google.android.material.textfield.TextInputLayout
         android:id="@+id/password"
         style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
         android:layout_
         android:layout_
         app:passwordToggleEnabled="true"
         android:hint="Password"
         android:layout_marginBottom="10dp">
    
         <com.google.android.material.textfield.TextInputEditText
             android:id="@+id/edtPassword"
             android:layout_
             android:layout_
             android:inputType="textPassword" />
    
     </com.google.android.material.textfield.TextInputLayout>
    
     <Button
         android:id="@+id/forgot_pass"
         android:layout_
         android:layout_
         android:layout_gravity="end"
         android:layout_marginBottom="10dp"
         android:background="#00FFFFFF"
         android:elevation="0dp"
         android:freezesText="false"
         android:text="Forget Password?" />
    
     <Button
         android:id="@+id/login_btn"
         android:layout_
         android:layout_
         android:background="@color/colorPrimary"
         android:padding="10dp"
         android:text="Login"
         android:textColor="@color/colorPrimaryLight"
         android:onClick="loginUser"/>
    
     <Button
         android:id="@+id/reg_btn"
         android:layout_
         android:layout_
         android:background="#00FFFFFF"
         android:padding="10dp"
         android:text="New user Register here."
         android:textColor="@color/colorSecondaryDark"
         android:onClick="regUser"/>
    

    login.java 代码

package com.example.d1;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;

public class login extends AppCompatActivity 

    TextInputLayout username, password;
    TextInputEditText edtUsername, edtPassword;
    Button login_btn, reg_btn;


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

        username = (TextInputLayout) findViewById(R.id.username);
        password = (TextInputLayout) findViewById(R.id.password);

        edtUsername = (TextInputEditText) findViewById(R.id.edtUsername);
        edtPassword = (TextInputEditText) findViewById(R.id.edtPassword);
    

    private boolean validateUsername()
        String val = username.getEditText().getText().toString();
        if(val.isEmpty())
            username.setError("fields cannot be empty");
            return false;
         else
            username.setError(null);
            return true;
        
    

    private boolean validatePassword()
        String val = password.getEditText().getText().toString();
        if(val.isEmpty())
            password.setError("fields cannot be empty");
            return false;
         else
            password.setError(null);
            return true;
        
    

    private void checkUser()

        final String userEnteredUsername = username.getEditText().getText().toString().trim();
        final String userEnteredPassword = password.getEditText().getText().toString().trim();

        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("users");

        Query checkUser = reference.orderByChild("username").equalTo(userEnteredUsername);

        checkUser.addListenerForSingleValueEvent(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) 

                if(dataSnapshot.exists())

                    username.setError(null);
                    username.setErrorEnabled(false);

                    String passwordFromDB = dataSnapshot.child(userEnteredUsername).child("password").getValue(String.class);

                    if(passwordFromDB.equals(userEnteredPassword))
                        Intent intent = new Intent( login.this, Dashboard.class);
                        startActivity(intent);
                     else
                        password.setError("wrong Password");
                        password.requestFocus();
                    

                 else
                    username.setError("no user found");
                    username.requestFocus();
                

            

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) 

            
        );
    

    public void loginUser(View View)
        if(!validateUsername() | !validatePassword())
            return;
        else 
            checkUser();
        
    

    public void regUser(View View)
        Intent intent = new Intent( login.this, Signup.class);
        startActivity(intent);
    



    错误日志
2020-07-18 19:16:12.864 7246-7246/com.example.d1 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.d1, PID: 7246
    com.google.firebase.database.DatabaseException: Failed to convert value of type java.lang.Long to String
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(com.google.firebase:firebase-database@@19.3.0:425)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@19.3.0:216)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@19.3.0:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@19.3.0:203)
        at com.example.d1.login$1.onDataChange(login.java:79)
        at com.google.firebase.database.Query$1.onDataChange(com.google.firebase:firebase-database@@19.3.0:179)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.3.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.3.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.3.0:55)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

【问题讨论】:

我猜你的数据快照中有很长的值并且你试图将它作为一个字符串来获取,你是否保存了任何长值? @taki eddine,请找到DB的截图。 i.stack.imgur.com/r9ilj.png 你可以试试这个 dataSnapshot.child(userEnteredUsername).child("password").getValue().toString() 而不是 String.class @taki eddine,非常感谢。你拯救了我的一天。请解释是什么问题。为什么它以前不起作用。再次感谢您的帮助。 原因是因为你使用了 string.class 而不是 tostring() , tostring 就像一个转换器,它将你的值转换为一个字符串 【参考方案1】:

这是您的主题的答案

dataSnapshot.child(userEnteredUsername).child("password").getValue().toString()

而不是 String.class

【讨论】:

以上是关于dataSnapshot 函数不起作用 - 函数调用时应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

从 '(_) throws -> ()' 类型的抛出函数到非抛出函数类型 '(DataSnapshot) -> Void' 的无效转换

Flutter:未为 DataSnapshot 类定义 forEach 方法

Functions Emulators 中的 DataSnapshot.ref 仅指向默认数据库

inspect.currentframe() 在某些实现下可能不起作用?

函数参数函数嵌套作用域名称空间

JavaScript数学函数不起作用并返回Nan