【问题标题】:Failed to convert value of type java.util.HashMap to String but no hashmap in code?无法将 java.util.HashMap 类型的值转换为 String 但代码中没有 hashmap?
【发布时间】:2017-11-22 00:35:19
【问题描述】:

我正在尝试将已添加到我的 Firebase 数据库的数据显示到 android。数据上传到数据库很好,但是当我尝试通过手机或模拟器显示时出现以下错误:

com.google.firebase.database.DatabaseException:转换失败 java.util.HashMap 类型的值到 String

在以下位置:

com.firebase.ui.database.FirebaseRecyclerAdapter.parseSnapshot(FirebaseRecyclerAdapter.java:147)

这是第 146 和 147 行的代码:

protected T parseSnapshot(DataSnapshot snapshot) {
    return snapshot.getValue(mModelClass);
}

此错误会导致应用程序崩溃且无法运行。我相信错误是由于我的 MainActivity 类中的这段代码造成的,因为当我删除应用程序将运行的 .child 元素时,但显然不显示数据。

mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");

我不确定为什么会抛出此错误,因为我在数据库中拥有的唯一数据类型是字符串,并且子“博客”在我的数据库中拼写正确。

另一条重要信息: 当我删除 firebase 中的“博客”子项时,该应用程序将运行。但是,一旦我将数据提交到 firebase,就会发生错误并且我的应用程序崩溃。

任何帮助将不胜感激,

这个类显示数据:

public class MainActivity extends AppCompatActivity {

    private RecyclerView mPostList;
    private DatabaseReference mDatabase;

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

        mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");

        mPostList = (RecyclerView) findViewById(R.id.post_list);
        mPostList.setHasFixedSize(true);
        mPostList.setLayoutManager(new LinearLayoutManager(this));
    }

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

        FirebaseRecyclerAdapter<Blog, BlogViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Blog, BlogViewHolder>(
                Blog.class,
                R.layout.post_row,
                BlogViewHolder.class,
                mDatabase
                ) {
            @Override
            protected void populateViewHolder(BlogViewHolder viewHolder, Blog model, int position) {

                viewHolder.setTitle(model.getTitle());
                viewHolder.setDesc(model.getDesc());
                viewHolder.setImage(getApplicationContext(), model.getImage());
            }
        };

        mPostList.setAdapter(firebaseRecyclerAdapter);
    }

    public static class BlogViewHolder extends RecyclerView.ViewHolder {

        View mView;

        public BlogViewHolder(View itemView) {
            super(itemView);

            mView = itemView;
        }

        public void setTitle(String title) {
            TextView post_title = (TextView)mView.findViewById(R.id.post_title);
            post_title.setText(title);
        }

        public void setDesc(String desc) {
            TextView post_desc = (TextView)mView.findViewById(R.id.post_desc);
            post_desc.setText(desc);
        }

        public void setImage(Context ctx, String image) {
            ImageView post_image = (ImageView) mView.findViewById(R.id.post_image);
            Picasso.with(ctx).load(image).into(post_image);
        }
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (item.getItemId()== R.id.action_add){
            startActivity(new Intent(MainActivity.this, PostActivity.class));
        }

        return super.onOptionsItemSelected(item);
    }
}

此类将数据发布到 firebase:

package infectionapp.com.infectionui;

public class PostActivity extends AppCompatActivity {

    private ImageButton mSelectImage;
    private Uri  mImageUri = null;
    private EditText mPostTitle;
    private EditText mPostDesc;
    private Button mSubmitBtn;

    private StorageReference mStorage;
    private DatabaseReference mDatabase;

   // private ProgressBar mProgress;
    private static final int GALLERY_REQUEST = 1;

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

        //Directs to root firebase storage
        mSelectImage = (ImageButton) findViewById(R.id.imageSelect);

        mStorage = FirebaseStorage.getInstance().getReference();
        mDatabase = FirebaseDatabase.getInstance().getReference().child("Blog");

        mPostTitle = (EditText) findViewById(R.id.titleField);
        mPostDesc = (EditText)findViewById(R.id.descField);
        mSubmitBtn = (Button) findViewById(R.id.submitBtn);

    //    mProgress = new ProgressBar(this);

        mSubmitBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startPosting();

            }
        });

        mSelectImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
                galleryIntent.setType("image/*");
                startActivityForResult(galleryIntent, GALLERY_REQUEST);
            }
        });
    }

    private void startPosting() {

       final String title_val = mPostTitle.getText().toString().trim();
       final String desc_val = mPostDesc.getText().toString().trim();

        if (!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(desc_val) && mImageUri != null){
                StorageReference filepath = mStorage.child("Post_Images").child(mImageUri.getLastPathSegment());

                filepath.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                    Uri downloadUrl = taskSnapshot.getDownloadUrl();

                        //Creates unique ID for post
                        DatabaseReference newPost = mDatabase.push();
                        newPost.child("title").setValue(title_val);
                        newPost.child("desc").setValue(desc_val);
                        newPost.child("image").setValue(downloadUrl).toString();

                        startActivity(new Intent(PostActivity.this, MainActivity.class));
                    }
                });
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == GALLERY_REQUEST && resultCode == RESULT_OK){
            mImageUri = data.getData();
            mSelectImage.setImageURI(mImageUri);

        }
    }
}

Database structure:

Child nodes within children:

Code screenshot

Error of updated code

【问题讨论】:

  • 分享您的数据库结构。
  • 我已经在最后添加了。请注意,当子元素“博客”被删除时,应用程序将发布到数据库。一旦它已经存在,它就会在尝试发布到它后崩溃。

标签: java android firebase-realtime-database hashmap runtime-error


【解决方案1】:

为了以最简单的方式获取数据,我建议您使用以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference blogRef = rootRef.child("Blog");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String desc = ds.child("desc").getValue(String.class);
            String title = ds.child("title").getValue(String.class);
            String image = ds.child("image").child("path").getValue(String.class);
            Log.d("TAG", desc + " / " + title + " / " + image);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
blogRef.addListenerForSingleValueEvent(eventListener);

您的输出将是:

tst / test / /v0/b/infectionui...

如您所见,我使用了 String 类。这也是您需要在 FirebaseRecyclerAdapter 中使用的内容。

如果您想从图像中获取另一个值,只需将.child("path") 更改为另一个孩子,比如说.child("schemeSpecificPart")

【讨论】:

  • 感谢 Alex 的帮助,我已经实现了您的代码,但同样的问题仍然存在。我在图像节点中添加了孩子的图像。这些是自动递增的。
  • 这两张截图有很大的不同。拳头不完整。现在告诉我,你要得到的确切值,我会再给你写代码。
  • 我的错。在我的 UI 上,我有一个卡片视图,它应该显示图像,标题和描述存储在“博客”节点中。看下面的代码,我没有在“图像”节点创建其他元素 DatabaseReference newPost = mDatabase.push(); newPost.child("title").setValue(title_val); newPost.child("desc").setValue(desc_val); newPost.child("image").setValue(downloadUrl).toString();
  • 我完全不理解你。请添加屏幕截图,在您想要获取的数据下划线。
  • 我有一个应用程序,用户可以在其中上传图片、标题和描述。图片取自用户的图库,title + desc 是简单的文字输入。当用户发帖时(参见 startPosting)。该方法然后将图片jpeg上传到firebase存储,并将title、image和desc上传到rootinfectionui/Blog下的firebase数据库。然后我希望这个“帖子”显示用户上传的标题 desc。当我的根目录中没有“博客”子项时,此代码有效。但是,一旦添加,应用程序就会崩溃,因此不会显示。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 2016-01-14
相关资源
最近更新 更多