我目前正在测试ValueEventListener的 onCancelled()
方法,以实现正确的firebase错误管理 . 到目前为止,我取得了成功,onCancelled()很好 . 我已为特定节点设置firebase规则以返回权限被拒绝错误 .
但我对如何在onCancelled()方法中管理全局变量感到困惑 . 为什么在 onCancelled()
中调用时全局变量似乎保持其默认初始状态?来自外部的变量更新不反映何时在此方法中调用它们,但在从 onDataChange()
和其他活动中方法调用时会反映出来 .
UPDATE NO. 2: 插入了firebase auth代码,添加了测试流程执行 . 还添加了@Doug Stevenson建议的日志输出 . 从日志中看来,onCancelled()只被调用一次(在app onCreate()期间) . 我认为这给了我一个错误的印象,即 currentSynId
从未改变,因为它的 Value 仍然是 Hello!!!
那里,我之前没有看过后记录 .
但是现在我看到有一个日志 W/RepoOperation: updateChildren at /2014 failed: DatabaseError: Permission denied
,每次调用时都会触发 R.id.btn_sync
(并且再也不会记录 onCancelled
的日志,其中更新的 currentSyncId
应该是) . 也许我应该重新解释一下我的问题?我想捕获当前取消日志被触发的实例 . 谢谢 .
UPDATE NO. 1 我从完整的代码中取出了相关的部分并替换了之前的代码:
...
public class Demo extends AppCompatActivity {
// Database reference
private DatabaseReference mFirebaseMain2014;
//
private FirebaseAuth mAuth;
public String currentSyncId = "Hello!!!";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
// Initialize firebase auth
mAuth = FirebaseAuth.getInstance();
mAuth.addAuthStateListener(new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if(mAuth.getCurrentUser() != null) {
Log.d("MAIN", "A user was logged in: " + mAuth.getCurrentUser().getUid());
initDatabase(mAuth.getCurrentUser().getUid());
}
findViewById(R.id.btn_sync).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
syncData();
}
});
findViewById(R.id.btn_echovalue).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
printId();
}
});
}
});
}
/**
* Initialize database and listeners
* @param userid
*/
public void initDatabase(String userid){
Log.d("MAIN", "Initialized databases");
// Initialize database references
mFirebaseMain2014 = FirebaseDatabase.getInstance().getReference("2014");
mFirebaseMain2014.child("app_final/" + userid).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
// data processing here..
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d("MAIN-ON-CANCELLED-EVENT", "An error occurred while syncing data: " +
databaseError.getMessage() + "\n id: " + currentSyncId);
}
});
}
/**
* Initiate firebase syncing (which will lead to Permission-Denied
*/
public void syncData(){
// Log values
Log.d("MAIN", "Initiating sync...");
currentSyncId = "00001";
// Set the dummy data that will be sent to firebase
HashMap map = new HashMap();
map.put(currentSyncId, "Hello, world!");
// Sync dummy data to firebase
mFirebaseMain2014.updateChildren(map);
Log.d("MAIN", "Sync called.");
}
/**
* Print the contents of global currentSyncId
*/
public void printId(){
Log.d("MAIN", "PRINTING CURRENT id value: " + currentSyncId + ", userid: " + getAuthUserId());
}
public String getAuthUserId(){
return mAuth.getCurrentUser().getUid();
}
}
TEST FLOW
-
加载了应用程序
-
按下
R.id.btn_echovalue
按钮 -
按下
R.id.btn_sync
按钮 -
按下
R.id.btn_echovalue
按钮
LOG OUTPUT
D/FirebaseAuth: Notifying id token listeners about user ( WN1b3pJyggNOvaoHDdtPsHrFLmG3 ).
I/FirebaseInitProvider: FirebaseApp initialization successful
D/FirebaseApp: Notifying auth state listeners.
Notified 0 auth state listeners.
D/MAIN: A user was logged in: WN1b3pJyggNOvaoHDdtPsHrFLmG3
D/MAIN: Initialized databases
W/SyncTree: Listen at /2014/app_final/WN1b3pJyggNOvaoHDdtPsHrFLmG3 failed: DatabaseError: Permission denied
D/MAIN-ON-CANCELLED-EVENT: An error occurred while syncing data: Permission denied
id: Hello!!!
I/FirebaseAuth: [FirebaseAuth:] Loading module via FirebaseOptions.
[FirebaseAuth:] Preparing to create service connection to gms implementation
D/FirebaseAuth: Notifying id token listeners about user ( WN1b3pJyggNOvaoHDdtPsHrFLmG3 ).
D/FirebaseApp: Notifying auth state listeners.
Notified 1 auth state listeners.
D/MAIN: PRINTING CURRENT id value: Hello!!!, userid: WN1b3pJyggNOvaoHDdtPsHrFLmG3
D/MAIN: Initiating sync...
D/MAIN: Sync called.
W/RepoOperation: updateChildren at /2014 failed: DatabaseError: Permission denied
D/MAIN: PRINTING CURRENT id value: 00001, userid: WN1b3pJyggNOvaoHDdtPsHrFLmG3
里面的日志 onCancelled()
射得很好 . 我期待看到
MAIN: An error occurred while syncing data: Permission denied.
Sync ID: 0001
但相反,我看到:
MAIN: An error occurred while syncing data: Permission denied.
Sync ID: Hello!!!
我需要在 onCancelled()
被触发时跟踪 currentSyncId
,以便我可以将应用程序中的本地同步状态引用重置为 false
.
我找了类似的案例和问题,但我找到的最接近的线程是如何调用 onCancelled
here和here,以及一些对onDataChange的引用 . 我在@vincrichaud here找到了一个有趣的答案,但我不确定这是否也适用于firebase android .
TIA!