When using Firebase, it is recommanded to use the push() command to manage data list. That's really fine, it provides a unique and ordered id for data pushed on the list.
在使用Firebase时,将命令使用push()命令管理数据列表。这真的很好,它为列表上推送的数据提供了一个惟一的和有序的id。
However, when Firebase goes offline (goOffline or NetworkOffline), if the app try to push a data on a list, the completion listener is not triggered, until the app goes back online : so there is no unique id until the line is on again.
但是,当Firebase脱机(goOffline或NetworkOffline)时,如果应用程序试图将数据推到列表上,那么完成监听器就不会被触发,直到该应用程序返回到在线状态:因此,直到这条线再次出现,才会有唯一的id。
1/ Is that the expected/normal behavior ?
这是期望/正常的行为吗?
2/ I didn"t see in the document (as far I remember), that the push command is working differently (or only in onlinemode) in offline state. Did I miss a line somewhere ?
2/我在文档中没有看到(据我所知),push命令在脱机状态下工作方式不同(或仅在onlinemode中)。我是不是在什么地方漏了一条线?
3/ My use case deal with data that own relationship. It means I want create an object (kind of master) in a list, and then reuse this master object id (provided by the completion listener) to build the relation between the master object and all other relevants objects. How may I deal with this offline state ?
3/我的用例处理与自己相关的数据。这意味着我想在列表中创建一个对象(某种主对象),然后重用这个主对象id(由完成侦听器提供)来构建主对象和所有其他相关对象之间的关系。我如何处理这种脱机状态?
Code Example :
代码示例:
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
Edit
编辑
Here is 4 ways to add data:
这里有四种添加数据的方法:
Push with Listener
推动与侦听器
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stack").push().setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView3)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
SetValue with Listener
SetValue与侦听器
findViewById(R.id.button4).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString()).setValue(counter++, new Firebase.CompletionListener() {
@Override
public void onComplete(FirebaseError firebaseError, Firebase firebase) {
((TextView) findViewById(R.id.textView4)).setText(String.valueOf(counter) + " - " + firebase.toString());
}
});
}
});
SetValue without Listener
SetValue没有监听器
findViewById(R.id.button5).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stackManual").child(UUID.randomUUID().toString());
temp.setValue(counter++);
((TextView) findViewById(R.id.textView5)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
}
});
Push without Listener
推动没有监听器
findViewById(R.id.button6).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stack").push();
temp.setValue(counter++);
((TextView) findViewById(R.id.textView6)).setText(String.valueOf(counter) + " - " + temp.getKey().toString());
}
});
IT APPEAR THAT THE LISTENERS ARE TRIGGERED ONLY WHEN THE DATA ARE IN THE DATABASE ON THE SERVER, AND NOT ON THE LOCAL DB ! - IS THAT CORRECT ? - IS THAT DOCUMENTED ?
似乎只有在服务器上的数据库中而不是本地数据库中,才会触发侦听器!-对吗?-有文件证明吗?
Because knowing that, a straight forward asynchronous application is more difficult to build now : encapsulation of asynchronous job may not be performed if offline, may it ?
因为知道了这一点,现在就很难构建一个直接向前的异步应用程序:如果脱机,异步作业的封装可能不会被执行,是吗?
10
so there is no unique id until the line is on again
所以没有唯一的id,直到这条线再次出现。
This last statement is not true. Firebase push ids are generated client-side and are statistically guaranteed to be unique.
最后一种说法是不正确的。客户端生成了Firebase push id,并且统计上保证是惟一的。
You can easily check this by splitting your operation:
你可以通过拆分你的操作来检查这个问题:
Firebase ref = new Firebase(getString(R.string.firebase_url));
Firebase newStackRef = ref.child("stack").push();
System.out.println("New key/push id: "+newStackRef.key());
newStackRef.setValue(counter++, new Firebase.CompletionListener() {
The logging output will show you the new push id, even when you're not connected to the network.
日志输出将显示新的push id,即使您没有连接到网络。
IT APPEAR THAT THE LISTENERS ARE TRIGGERED ONLY WHEN THE DATA ARE IN THE DATABASE ON THE SERVER, AND NOT ON THE LOCAL DB! IS THAT CORRECT ?
似乎只有当数据在服务器上的数据库中,而不是在本地数据库上时,才触发侦听器。那是正确的吗?
The completion listeners will only trigger once the data has been committed on the server.
只有在服务器上提交数据之后,完成监听器才会触发。
From the guide on saving data:
保存资料指引:
If you'd like to know when your data has been committed, you can add a completion listener. Both setValue() and updateChildren() take an optional completion listener that is called when the write has been committed to the database.
如果您想知道什么时候提交了数据,可以添加一个完成侦听器。setValue()和updateChildren()都接受一个可选的完成侦听器,当写入数据库时,该侦听器将被调用。
However, regular event listeners (like those created with addValueEventListener()) will be triggered both for local and remote edits. These are the listeners you should use to render your UI, etc.
但是,常规的事件监听器(比如使用addValueEventListener()创建的那些监听器)将在本地和远程编辑时被触发。这些是您应该用来呈现UI的监听器,等等。
1
Following what @Andrew-lee and @Frank-fan-puffelen (thank to both agree on that please), the solution appear to be :
按照@Andrew-lee和@Frank-fan-puffelen(谢谢双方都同意)的说法,解决方案似乎是:
Schedule your job inside the listener (here update the UI, but could be another command)
在侦听器中安排您的工作(这里更新UI,但是可以是另一个命令)
findViewById(R.id.button7).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Firebase temp = new Firebase(getString(R.string.firebase_url)).child("stack").push();
temp.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
((TextView) findViewById(R.id.textView7)).setText(String.valueOf(counter) + " - " + dataSnapshot.getKey().toString());
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
temp.setValue(counter++);
}
});