我在访问子节点时遇到问题。 (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 实时数据库 - 增量报告)的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 实时规则如何检查具有 AutoID 的节点是不是包含正确的数据