You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Firebase 查询实现:如何获取并展示用户已保存的帖子

Got it, let's figure out how to fetch and display your user's saved posts from Firebase. I'll walk you through the process step-by-step, using your existing PostAdapter as a foundation.

Step 1: Understand Your Firebase Data Structure

From your adapter code, I can see you're storing saved posts under Users/{uid}/saved/{postId}. To display these posts, we first need to:

  1. Fetch all postIds from the user's saved node
  2. Use those IDs to pull the full post details from your main Posts node (I'll assume your posts are stored here; adjust the path if your structure is different)

Step 2: Implement Fetch Logic in Your Saved Posts Activity

Here's how to set up the query and populate your RecyclerView in your saved posts Activity:

public class SavedPostsActivity extends AppCompatActivity {

    private RecyclerView mSavedPostsRecycler;
    private PostAdapter mPostAdapter;
    private List<Post> mSavedPostsList;

    // Firebase References
    private DatabaseReference mUserSavedPostsRef;
    private DatabaseReference mAllPostsRef;
    private FirebaseUser mCurrentUser;

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

        // Initialize RecyclerView
        mSavedPostsRecycler = findViewById(R.id.saved_posts_recycler);
        mSavedPostsRecycler.setLayoutManager(new LinearLayoutManager(this));
        mSavedPostsList = new ArrayList<>();
        mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
        
        // Initialize Firebase references
        mUserSavedPostsRef = FirebaseDatabase.getInstance().getReference()
                .child("Users").child(mCurrentUser.getUid()).child("saved");
        mAllPostsRef = FirebaseDatabase.getInstance().getReference().child("Posts"); // Adjust path if needed

        // Set up adapter
        mPostAdapter = new PostAdapter(mSavedPostsList, mUserSavedPostsRef.getParent(), this);
        mSavedPostsRecycler.setAdapter(mPostAdapter);

        // Start fetching saved posts
        loadSavedPosts();
    }

    private void loadSavedPosts() {
        mUserSavedPostsRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot savedSnapshot) {
                mSavedPostsList.clear(); // Clear old data first

                if (savedSnapshot.exists()) {
                    int totalSavedPosts = (int) savedSnapshot.getChildrenCount();
                    int fetchedCount = 0;

                    // Loop through each saved post ID
                    for (DataSnapshot postIdSnap : savedSnapshot.getChildren()) {
                        String postId = postIdSnap.getKey();

                        // Fetch full post details from the main Posts node
                        mAllPostsRef.child(postId).addListenerForSingleValueEvent(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot postSnapshot) {
                                // Convert snapshot to your Post object (ensure Post has a no-arg constructor + getters/setters)
                                Post savedPost = postSnapshot.getValue(Post.class);
                                if (savedPost != null) {
                                    savedPost.setPostId(postId); // Explicitly set post ID if your model needs it
                                    mSavedPostsList.add(savedPost);
                                }

                                fetchedCount++;
                                // Update adapter only once all posts are fetched
                                if (fetchedCount == totalSavedPosts) {
                                    mPostAdapter.notifyDataSetChanged();
                                }
                            }

                            @Override
                            public void onCancelled(DatabaseError databaseError) {
                                fetchedCount++;
                                Toast.makeText(SavedPostsActivity.this, "Failed to load post: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                } else {
                    // Handle empty state (no saved posts)
                    mPostAdapter.notifyDataSetChanged();
                    Toast.makeText(SavedPostsActivity.this, "You haven't saved any posts yet", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(SavedPostsActivity.this, "Failed to load saved posts: " + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Step 3: Optional Adapter Improvement

Add a method to your PostAdapter to refresh the post list more cleanly (instead of relying on notifyDataSetChanged directly every time):

// Add this to your PostAdapter class
public void updateSavedPosts(List<Post> updatedPosts) {
    mPostList.clear();
    mPostList.addAll(updatedPosts);
    notifyDataSetChanged();
}

Then replace mPostAdapter.notifyDataSetChanged(); in loadSavedPosts() with:

mPostAdapter.updateSavedPosts(mSavedPostsList);

Key Notes

  • Firebase Model Requirements: Your Post class must have a no-argument constructor, and all fields must have corresponding getters/setters for Firebase to convert the DataSnapshot into a Post object.
  • Security Rules: Make sure your Firebase Database rules allow users to read their own saved node and the main Posts node. Example rules:
    {
      "rules": {
        "Users": {
          "$uid": {
            ".read": "$uid === auth.uid",
            ".write": "$uid === auth.uid"
          }
        },
        "Posts": {
          ".read": "auth != null", // Allow authenticated users to read posts
          ".write": "auth != null"
        }
      }
    }
    
  • Real-Time Updates: The addValueEventListener will automatically refresh the list if the user saves/unsaves posts while the Activity is active. If you don't need real-time updates, use addListenerForSingleValueEvent instead.

内容的提问来源于stack exchange,提问作者Cariweb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:25:40