我是Java / Android的新手,第一个计时器
我开发了一个使用SetValue()更新Firebase数据库的类,如果OnComplete(DatabaseReference.CompletionListener)出错,则会抛出异常。
在我的活动中,我已经在Try-Catch中调用了方法(在上面的课程中)。
问题如下:
请注意我故意改变了firebase安全性,以便用户无法写入。
自定义类代码:
package com.mypack.fdbmanager;
import android.app.Activity;
import android.content.Context;
import android.widget.Toast;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class FbDbManager {
FirebaseDatabase MyDb = FirebaseDatabase.getInstance();
DatabaseReference MyRef = MyDb.getReference("Users/User_01");
DatabaseReference MyDataRef = MyRef.child("Message");
Context MyContext;
public FbDbManager(Context context) {
MyContext = context;
}
public void UpdateUser(String valueToUpdate) {
MyDataRef.setValue(valueToUpdate, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
throw databaseError.toException();
} else {
// Do nothing
}
}
});
}
}
这是我的活动代码:
package com.mypack.fdbmanager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
FbDbManager myDbRef;
Button myButton_Send;
EditText myEdiText_Message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDbRef = new FbDbManager(this);
myButton_Send = findViewById(R.id.button_Send);
myEdiText_Message = findViewById(R.id.editText_Message);
myButton_Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
UpdateUser();
}
});
}
private void UpdateUser() {
try {
myDbRef.UpdateUser(myEdiText_Message.getText().toString().trim());
Toast.makeText(getApplicationContext(), "Data saved successfully.", Toast.LENGTH_SHORT).show();
} catch (Throwable e) {
Toast.makeText(getApplicationContext(), e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
return;
}
}
}
以下是跟踪:
V / FA:处理排队的服务任务:1 E / FA:丢弃数据。 无法将事件发送到服务D / EGL_emulation:eglMakeCurrent: 0xa9c06440:ver 2 0(tinfo 0xa9c035f0)D / EGL_emulation: eglMakeCurrent:0xa9c06440:ver 2 0(tinfo 0xa9c035f0) W / RepoOperation:setValue at / Users / User_01 / Message failed:DatabaseError:Permission denied I / zygote:部分代码缓存 集合,代码= 61KB,数据= 49KB I / zygote:代码缓存后 集合,代码= 61KB,数据= 49KB I / zygote:增加代码缓存 容量为256KB
答案 0 :(得分:1)
看起来您假设您的CompletionListener与对UpdateUser的调用同步执行。这不是它的工作方式。异步调用的回调 - 对MyDataRef.setValue()
的调用总是立即返回,并且稍后调用回调未知的时间。同时,您的UpdateUser方法在不知道任何问题的情况下返回,因为异常不能“逃避”该函数。在每个方法顶部使用断点的调试器中运行它,或者在每行之间放置日志语句,以了解它是如何工作的。
要解决此问题,tour数据库帮助程序方法应该接受并调用异步回调。他们不应该期望阻止查询的结果。你有一些非常重要的重组要做。
答案 1 :(得分:0)
权限被拒绝是用户未经授权时出现的错误。更改数据库规则:
如果用户被授权或登录
,此规则将允许数据库读写{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
此规则允许数据库读写,而不检查用户是否已获得授权。
{
"rules": {
".read": "true",
".write": "true"
}
}