我在访问子节点时遇到问题。 (firebase 实时数据库 - 增量报告)

Posted

技术标签:

【中文标题】我在访问子节点时遇到问题。 (firebase 实时数据库 - 增量报告)【英文标题】:I have a problem accessing child nodes. (firebase realtime database - increment reports) 【发布时间】:2022-01-05 03:34:12 【问题描述】:

这是我的数据结构。

"Posts" : 
  "-MpVVpVIqmn0Iu78hDRp" : 
    "description" : "",
    "picture" : "",
    "postKey" : "",
    "reports" : 0,
    "timeStamp" : 1638001760487,
    "title" : "",
    "userId" : "",
    "userPhoto" : ""
  ,
  "-MpVcioadtvRBRaa0n96" : 
    "description" : "",
    "picture" : "",
    "postKey" : "",
    "reports" : 0,
    "timeStamp" : 1638003830234,
    "title" : "",
    "userId" : "",
    "userPhoto" : ""
  ,

我想访问“报告”部分。所以我用

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("Posts").child("reports").setValue(1);

但它会在 Posts not below "-MpVVpVIqmn0Iu78hDRp" this 下面创建报告值 1。 我想增加报告。但我不知道如何处理报告节点。

这是我的完整代码

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_post_detail);
    imm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
    et = (EditText)findViewById(R.id.post_detail_comment);



    // let's set the statue bar to transparent


    // ini Views
    RvComment = findViewById(R.id.rv_comment);
    imgPost =findViewById(R.id.post_detail_img);
    imgUserPost = findViewById(R.id.post_detail_user_img);
    imgCurrentUser = findViewById(R.id.post_detail_currentuser_img);

    txtPostTitle = findViewById(R.id.post_detail_title);
    txtPostDesc = findViewById(R.id.post_detail_desc);
    txtPostDateName = findViewById(R.id.post_detail_date_name);

    editTextComment = findViewById(R.id.post_detail_comment);
    btnAddComment = findViewById(R.id.post_detail_add_comment_btn);
    btnDeletePost = findViewById(R.id.button_delete);
    btnnoti = findViewById(R.id.button_noti);
    btncommentnoti = findViewById(R.id.comment_noti);


    firebaseAuth = FirebaseAuth.getInstance();
    firebaseUser = firebaseAuth.getCurrentUser();
    firebaseDatabase = FirebaseDatabase.getInstance();
    // add post delete button
    mDatabase= FirebaseDatabase.getInstance().getReference();

    myUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    //게시글 신고기능
    btnnoti.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
            rootRef.child("Posts").child("reports").setValue(1);

        
    );

    btnDeletePost.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            //여기 수정 주의 UId.equals(myUid)
            if (true)
                Toast.makeText(PostDetailActivity.this,"삭제중...",Toast.LENGTH_SHORT).show();
                beginDelete();
                onBackPressed();
            

        
    );

    // add Comment button click listener

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

            btnAddComment.setVisibility(View.INVISIBLE);
            DatabaseReference commentReference = firebaseDatabase.getReference(COMMENT_KEY).child(PostKey).push();
            String comment_content = editTextComment.getText().toString();
            String uid = firebaseUser.getUid();
            String uname = firebaseUser.getDisplayName();
            if (firebaseUser.getPhotoUrl()!=null)
                String uimg = firebaseUser.getPhotoUrl().toString();
                Comment comment = new Comment(comment_content,uid,uimg,uname);
                commentReference.setValue(comment).addOnSuccessListener(new OnSuccessListener<Void>() 
                    @Override
                    public void onSuccess(Void aVoid) 
                        showMessage("댓글이 등록되었습니다.");
                        editTextComment.setText("");
                        btnAddComment.setVisibility(View.VISIBLE);
                    
                ).addOnFailureListener(new OnFailureListener() 
                    @Override
                    public void onFailure(@NonNull Exception e) 
                        showMessage("fail to add comment : "+e.getMessage());
                    
                );

            
            else
                String usphoto =Integer.toString(R.drawable.userphoto);
                Comment comment = new Comment(comment_content,uid,usphoto,uname);
                commentReference.setValue(comment).addOnSuccessListener(new OnSuccessListener<Void>() 
                    @Override
                    public void onSuccess(Void aVoid) 
                        showMessage("comment added");
                        editTextComment.setText("");
                        btnAddComment.setVisibility(View.VISIBLE);
                    
                ).addOnFailureListener(new OnFailureListener() 
                    @Override
                    public void onFailure(@NonNull Exception e) 
                        showMessage("fail to add comment : "+e.getMessage());
                    
                );
            




        
    );


    // now we need to bind all data into those views
    // first we need to get post data
    // we need to send post detail data to this activity first ...
    // now we can get post data



    // 게시글 사진 백지 케이스
    postImage = getIntent().getExtras().getString("postImage") ;
    if(postImage!=null)
        Glide.with(this).load(postImage).into(imgPost);
    
    else
        Glide.with(this).load(R.drawable.whitepaper).into(imgPost);
    


    String postTitle = getIntent().getExtras().getString("title");
    txtPostTitle.setText(postTitle);

    String userpostImage = getIntent().getExtras().getString("userPhoto");
    if (userpostImage!=null)
        Glide.with(this).load(userpostImage).into(imgUserPost);
    
    else 
        Glide.with(this).load(R.drawable.userphoto).into(imgUserPost);
    

    String postDescription = getIntent().getExtras().getString("description");
    txtPostDesc.setText(postDescription);

    // set comment user image
    if (firebaseUser.getPhotoUrl()!=null)
        Glide.with(this).load(firebaseUser.getPhotoUrl()).into(imgCurrentUser);
    
    else
        Glide.with(this).load(R.drawable.userphoto).into(imgCurrentUser);
    
    // get post key
    PostKey = getIntent().getExtras().getString("postKey");

    String date = timestampToString(getIntent().getExtras().getLong("postDate"));
    txtPostDateName.setText(date);
    // get post uid
    UId = getIntent().getExtras().getString("userId");



    // ini Recyclerview Comment
    iniRvComment();




private void beginDelete() 


    //서버 관리용 개발자 옵션
    if (myUid.equals("k1kn0JF5idhrMzuw46GarEIBgPw2")) 

        long tlong = System.currentTimeMillis(); long ttime;
        ttime = tlong - 3*24*60*60*1000;
        DatabaseReference db = FirebaseDatabase.getInstance().getReference();
        Query queryByTimestamp = db.child("Posts").orderByChild("timeStamp").endAt(ttime);
        queryByTimestamp.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
            @Override
            public void onComplete(@NonNull Task<DataSnapshot> task) 
                if (task.isSuccessful()) 
                    for (DataSnapshot ds : task.getResult().getChildren()) 
                        ds.getRef().removeValue();
                        Toast.makeText(PostDetailActivity.this,"게시글이 삭제되었습니다.",Toast.LENGTH_SHORT).show();
                    
                 else 
                    Log.d("TAG", task.getException().getMessage());
                    Toast.makeText(PostDetailActivity.this,"게시글이 삭제되지않았습니다.",Toast.LENGTH_SHORT).show();

                
            
        );

    
    else if (UId.equals(myUid)) 
        DatabaseReference db = FirebaseDatabase.getInstance().getReference();
        Query queryByTimestamp = db.child("Posts").orderByChild("postKey").equalTo(PostKey);
        queryByTimestamp.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() 
            @Override
            public void onComplete(@NonNull Task<DataSnapshot> task) 
                if (task.isSuccessful()) 
                    for (DataSnapshot ds : task.getResult().getChildren()) 
                        ds.getRef().removeValue();
                        Toast.makeText(PostDetailActivity.this, "게시글이 삭제되었습니다.", Toast.LENGTH_SHORT).show();
                    
                 else 
                    Log.d("TAG", task.getException().getMessage());
                    Toast.makeText(PostDetailActivity.this, "게시글이 삭제되지않았습니다.", Toast.LENGTH_SHORT).show();

                
            
        );
    
    else
        Toast.makeText(PostDetailActivity.this,"다른 사용자의 게시글입니다.",Toast.LENGTH_SHORT).show();
    



public void linearOnClick(View v) 
    imm.hideSoftInputFromWindow(et.getWindowToken(), 0);



private void iniRvComment() 

    RvComment.setLayoutManager(new LinearLayoutManager(this));

    DatabaseReference commentRef = firebaseDatabase.getReference(COMMENT_KEY).child(PostKey);
    commentRef.addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            listComment = new ArrayList<>();
            for (DataSnapshot snap:dataSnapshot.getChildren()) 

                Comment comment = snap.getValue(Comment.class);
                listComment.add(comment) ;

            

            commentAdapter = new CommentAdapter(getApplicationContext(),listComment);
            RvComment.setAdapter(commentAdapter);


        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );






private void showMessage(String message) 

    Toast.makeText(this,message,Toast.LENGTH_LONG).show();




private String timestampToString(long time) 

    Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
    calendar.setTimeInMillis(time);
    String date = DateFormat.format("yyyy-MM-dd",calendar).toString();
    return date;



这是我的问题的一部分

btnnoti.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
            rootRef.child("Posts").child("reports").setValue(1);

        
    );

我也试过 orderbychild,但我认为这不是正确的代码。

【问题讨论】:

请仅使用android-studio 标签来回答有关 Android Studio IDE 本身的问题。对于一般的 Android 编程问题,请使用android 标签。 【参考方案1】:

这段代码:

rootRef.child("Posts").child("reports").setValue(1);

您告诉数据库将/Posts/reports 的值设置为1,这正是它所做的。


如果你想增加一个节点的当前值,你可以use the atomic increment operation:

rootRef.child("Posts").child("reports").setValue(ServerValue.increment(1));

如果要增加Posts 下特定节点的reports 属性,则需要知道该节点的键。例如:

rootRef.child("Posts/-MpVVpVIqmn0Iu78hDRp/reports").setValue(ServerValue.increment(1));

如果您不知道要递增的节点的键,但确实知道其他一些唯一(足够)标识要更新的节点的值,您可以use a query 到找到钥匙。

例如,用特定的postKey 更新所有节点:

Query query = rootRef.child("Posts").orderByChild("postKey").equalTo("thePostKeyValue");
query.addListenerForSingleValueEvent(new ValueEventListener() 
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) 
        for (DataSnapshot postSnapshot: dataSnapshot.getChildren()) 
            postSnapshot.getReference().child("reports").setValue(ServerValue.increment(1));
        
    

    @Override
    public void onCancelled(DatabaseError databaseError) 
        throw databaseError.toException();
    

【讨论】:

感谢您回答我!但是我可以通过代码找到 -MpVVpVIqmn0Iu78hDRp child 吗?不是通过某些键值 -MpVVpVIqmn0Iu78hDRp .. 因为我的帖子有 push() 并制作 -MpVVpVIqmn0Iu78hDRp。我想访问除 -MpVVpVIqmn0Iu78hDRp 值之外的报告节点。 要将值写入 Firebase 中的路径,您必须知道完整、准确的路径。如果你不知道要写reports 的节点的密钥,你知道它做什么。如果您知道其他一些唯一值,您可以use a query 查找符合该条件的节点。我还在我的答案中添加了如何执行此操作的代码示例。 谢谢!!我解决了!下一步是忽略重复请求。

以上是关于我在访问子节点时遇到问题。 (firebase 实时数据库 - 增量报告)的主要内容,如果未能解决你的问题,请参考以下文章

根据特定值查询子节点(Swift 3、Firebase)

Firebase -- 批量删除子节点

Firebase 实时规则如何检查具有 AutoID 的节点是不是包含正确的数据

如何在现有的 Firebase json 结构下添加子节点?

设置值 Firebase 时重复子节点

Android Firebase如何获取包含列表的孩子