Android firebase - 为什么点击星标总是删除一个子值?

时间:2017-02-04 15:25:08

标签: android firebase

这是FreeboardPost.java

public class FreeboardPost
{
    public String imageUrl;
    public String uid;
    public String author;
    public String title;
    public String body;
    public int starCount = 0;


    public Map<String, Boolean> stars = new HashMap<>();

    public FreeboardPost()
    {
    }

    public FreeboardPost(String uid, String author, String title, String body, String imageUrl)
    {
        this.imageUrl = imageUrl;
        this.uid = uid;
        this.author = author;
        this.title = title;
        this.body = body;

    }

    @Exclude
    public Map<String, Object> toMap()
    {
        HashMap<String, Object> result = new HashMap<>();
        result.put("image", imageUrl);
        result.put("uid", uid);
        result.put("author", author);
        result.put("title", title);
        result.put("body", body);
        result.put("starCount", starCount);
        result.put("stars", stars);

        return result;
    }

}

这是FreeboardPostViewHolder.java

public class FreeboardPostViewHolder extends RecyclerView.ViewHolder
{
    public TextView freeboardtitleView;
    public TextView freeboardauthorView;
    public ImageView freeboardstarView;
    public TextView freeboardnumStarsView;
    public TextView freeboardbodyView;
    public CircleImageView freeboardprofileView;

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

        freeboardtitleView = (TextView) itemView.findViewById(R.id.freeboard_post_title);
        freeboardauthorView = (TextView) itemView.findViewById(R.id.freeboard_post_author);
        freeboardstarView = (ImageView)itemView.findViewById(R.id.freeboard_star);
        freeboardnumStarsView = (TextView)itemView.findViewById(R.id.freeboard_post_num_stars);
        freeboardbodyView = (TextView)itemView.findViewById(R.id.freeboard_post_body);
        freeboardprofileView = (CircleImageView)itemView.findViewById(R.id.freeboard_post_author_photo);
    }

    public void bindToPost(FreeboardPost freeboardpost, View.OnClickListener starClickListener)
    {
        freeboardtitleView.setText(freeboardpost.title);
        freeboardauthorView.setText(freeboardpost.author);
        freeboardnumStarsView.setText(String.valueOf(freeboardpost.starCount));
        freeboardbodyView.setText(freeboardpost.body);
        freeboardstarView.setOnClickListener(starClickListener);
    }
}

这是FreeboardPostListFragment.java

public abstract class FreeboardPostListFragment extends Fragment
{
    private static final String TAG = "FreeBoardPostListFragment";

    private DatabaseReference mDatabase;

    private FirebaseRecyclerAdapter<FreeboardPost, FreeboardPostViewHolder> mAdapter;
    private RecyclerView mRecycler;
    private LinearLayoutManager mManager;

    private DatabaseReference mPostReference;
    private ValueEventListener mPostListener;

    private String image;

    public FreeboardPostListFragment()
    {

    }

    @Override
    public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        super.onCreateView(inflater, container, savedInstanceState);
        View rootView = inflater.inflate(R.layout.freeboard_fragment_all_posts, container, false);

        mDatabase = FirebaseDatabase.getInstance().getReference();

        mRecycler = (RecyclerView)rootView.findViewById(R.id.freeboard_messages_list);
        mRecycler.setHasFixedSize(true);

        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState)
    {
        super.onActivityCreated(savedInstanceState);

        mManager = new LinearLayoutManager(getActivity());
        mManager.setReverseLayout(true);
        mManager.setStackFromEnd(true);
        mRecycler.setLayoutManager(mManager);

        Query postsQuery = getQuery(mDatabase);

        mAdapter = new FirebaseRecyclerAdapter<FreeboardPost, FreeboardPostViewHolder>(FreeboardPost.class, R.layout.freeboard_item_post, FreeboardPostViewHolder.class, postsQuery)
        {
            @Override
            protected void populateViewHolder(final FreeboardPostViewHolder viewHolder, final FreeboardPost model, final int position)
            {
                final DatabaseReference postRef = getRef(position);

                final String postKey = postRef.getKey();

                mPostReference = FirebaseDatabase.getInstance().getReference().child("FreeboardPost").child(postKey);

                viewHolder.itemView.setOnClickListener(new View.OnClickListener()
                {
                    @Override
                    public void onClick(View v)
                    {
                        Intent intent = new Intent(getActivity(), FreeBoardPostDetailActivity.class);
                        intent.putExtra(FreeBoardPostDetailActivity.EXTRA_POST_KEY, postKey);
                    startActivity(intent);
                    }
                });

                if(model.stars.containsKey(getUid()))
                {
                    viewHolder.freeboardstarView.setImageResource(R.drawable.ic_toggle_star_24);
                }
                else
                {
                    viewHolder.freeboardstarView.setImageResource(R.drawable.ic_toggle_star_outline_24);
                }

                viewHolder.bindToPost(model, new View.OnClickListener()
                {
                    @Override
                    public void onClick(View starView)
                    {
                        DatabaseReference globalPostRef = mDatabase.child("FreeboardPost").child(postRef.getKey());
                        DatabaseReference userPostRef = mDatabase.child("FreeboardUserPost").child(model.uid).child(postRef.getKey());

                        onStarClicked(globalPostRef);
                        onStarClicked(userPostRef);
                    } 
                });
            }
        };

        mRecycler.setAdapter(mAdapter);
    }

    private void onStarClicked(DatabaseReference postRef)
    {
        postRef.runTransaction(new Transaction.Handler()
        {
            @Override
            public Transaction.Result doTransaction(MutableData mutableData)
            {
                FreeboardPost p = mutableData.getValue(FreeboardPost.class);

                if(p == null)
                {
                    return Transaction.success(mutableData);
                }

                if(p.stars.containsKey(getUid()))
                {
                    p.starCount = p.starCount - 1;
                    p.stars.remove(getUid());

                }
                else
                {
                    p.starCount = p.starCount + 1;
                    p.stars.put(getUid(), true);
                }

                mutableData.setValue(p);
                return Transaction.success(mutableData);
            }

            @Override
            public void onComplete(DatabaseError databaseError, boolean b, DataSnapshot dataSnapshot)
            {
            }
        });
    }

    public String getUid()
    {
        return FirebaseAuth.getInstance().getCurrentUser().getUid();
    }

    public abstract Query getQuery(DatabaseReference databaseReference);
}

这是freeboard_include_post_author.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:gravity="center_vertical"
                  android:orientation="horizontal">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/freeboard_post_author_photo"
            android:layout_width="40dp"
            android:layout_height="40dp"
            app:civ_border_width="2dp"
            app:civ_border_color="#FF000000">
        </de.hdodenhof.circleimageview.CircleImageView>

        <TextView
            android:id="@+id/freeboard_post_author"
            style="@style/Base.TextAppearance.AppCompat.Small"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:gravity="center_vertical"
            tools:text="someauthor@email.com" />

    </LinearLayout>

这是freeboard_item_post.xml

<?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="1dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp">

        <ImageView
            android:id="@+id/freeboard_post_image"
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_marginRight="10dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:scaleType="centerCrop"
            android:src="@drawable/profile"/>

        <RelativeLayout
            android:id="@+id/freeboard_text_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@id/freeboard_post_image">

            <LinearLayout
                android:id="@+id/freeboard_star_layout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBottom="@+id/freeboard_post_author_layout"
                android:layout_alignParentRight="true"
                android:layout_alignTop="@+id/freeboard_post_author_layout"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <ImageView
                    android:id="@+id/freeboard_star"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="5dp"
                    android:background="?attr/selectableItemBackground"
                    android:src="@drawable/ic_toggle_star_outline_24" />

                <TextView
                    android:id="@+id/freeboard_post_num_stars"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    tools:text="7" />

            </LinearLayout>

            <include
                android:id="@+id/freeboard_post_text"
                layout="@layout/freeboard_include_post_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_marginLeft="5dp"
                android:layout_marginTop="10dp" />

            <include
                android:id="@+id/freeboard_post_author_layout"
                android:layout_below="@+id/freeboard_post_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                layout="@layout/freeboard_include_post_author"
                android:layout_marginTop="10dp"
                android:layout_alignParentLeft="true" />

        </RelativeLayout>
    </RelativeLayout>

</android.support.v7.widget.CardView>

非常感谢您阅读我的长码。我很难用星形按钮显示用户的图像。当我点击星标时,firebase立即从同一个孩子中删除“图像”值。

这是在我点击星标之前 This is before I click star

这是在我点击星形按钮之后。 enter image description here

我100%确定没有删除子项或值的代码..但为什么它会从子项中删除我的图像地址..?我很好奇。谢谢!

1 个答案:

答案 0 :(得分:0)

您没有发布在数据库中创建FreeboardPost实例的代码。我猜你正在使用toMap(),因为它将图片网址存储在名为image的字段中,该字段显示在您发布的数据库示例中。

在您的交易中,您使用Firebase来序列化/反序列化FreeboardPost。它希望在名为imageUrl的字段中找到图像URL,因为这是您班级中的公共字段名称。当您发布的节点被读取时,没有名为imageUrl的字段,因此创建的FreeboardPost实例对该字段值为null。编写实例时,没有为imageUrl写入值,因为它为空,并且image的先前数据库值丢失,因为FreeboardPost没有具有该名称的字段。

如果要使用Firebase功能序列化/反序列化FreeboardPost,则应将它们用于所有数据库读取和写入。使用带有映射的updateMap()setValue()来编写实例,然后使用POJO类来读取命名不匹配的风险。