Firebase实时数据库-存储来自用户输入的多个节点

时间:2020-04-19 09:28:17

标签: java firebase android-studio firebase-realtime-database

我是Firebase和android studio的新手,我试图将多个节点保存在Firebase中,我要为“用户”保存一个节点,但是我需要为“预算”类别添加另一个节点保存。最初我以为OnClickListener出现问题,但经检查可以正常工作。 这是在我的注册中发送用户数据的代码:

 private void sendUserData(){
        String UserID = firebaseAuth.getUid();
        RegDB regDB = new RegDB(emailDb, nameDb, passwordDb);
        mDatabase.child("Users").child(UserID).setValue(regDB);
    }

这是我的“预算”页面中用于发送用户数据的代码:

 private void sendUserData() {
        String UserID = firebaseAuth.getUid();
        CategoriesDB catDb = new CategoriesDB(travel_budget, entertainment_budget, fitness_budget, beauty_budget, clothes_budget, holiday_budget, food_budget, mobile_budget);
        mDatabase.child("Users").child(UserID).child("Categories").setValue(catDb);
    }

尽管我尝试输入预算,但Firebase会为每个注册人员分配一个唯一的用户ID,并且此ID存储在实时数据库和身份验证中,我仍然会收到此错误:

java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()

作为参考,这是我的“注册”页面的OnClickListener:

button_Upload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (validate()) {
                    String emailDb = email.getText().toString().trim();
                    String passwordDb = password.getText().toString().trim();

                    firebaseAuth.createUserWithEmailAndPassword(emailDb, passwordDb).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                        @Override
                        public void onComplete(@NonNull Task<AuthResult> task) {
                            if (task.isSuccessful()) {
                                sendUserData();
                                firebaseAuth.signOut();
                                Toast.makeText(Register.this, "Successfully Registered!", Toast.LENGTH_SHORT).show();
                                finish();
                                startActivity(new Intent(Register.this, Menu.class));
                            } else {
                                Toast.makeText(Register.this, "Registration Failed.", Toast.LENGTH_SHORT).show();
                            }
                        }
                    });

“我的预算”页面的OnClickListener:

btn_subCat.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(validate()){
                sendUserData();
                Toast.makeText(Categories.this, "Completed!", Toast.LENGTH_LONG).show();
                finish();
                startActivity(new Intent(Categories.this, Menu.class ));
            }else{
                Toast.makeText(Categories.this, "Submission failed", Toast.LENGTH_LONG).show();
            }
        }

    });

1 个答案:

答案 0 :(得分:0)

我并没有真正的经验,但是我认为在尝试从API获取和更新信息时遇到了类似的问题。我认为您的问题来自多线程。调用getUid()函数时,它将创建一个新线程以获取所需的信息。此任务需要一些时间来完成其任务并从数据库中获取ID。但是,您的sendUserData()函数需要较少的时间来完成其任务。因此,您可以从sendUserData()函数转到代码的第三行,在该线程中,您可以在线程完成操作之前使用UserID变量,而剩下一个空变量。

如果这是问题所在,则可以通过让应用程序等待线程完成来解决,或者可以在点击按钮之前获取用户ID。我认为第一种方法更好,但是当我解决自己的问题时,却找不到解决此问题的好方法。

对于第二种方法,您可以在onCreate()方法的开头简单地创建UserID变量,然后在其中分配它的值。这样,您将在创建活动时创建线程,从数据库中获取信息并关闭线程。当您尝试调用sendUserData()函数时,已经为您准备好了userId。

因此,不确定是否要这样做,但是请尝试一下:)