Como a sincronização do Firebase funciona, com dados compartilhados?
Eu uso o Firebase para lidar com o tópico Auth do meu aplicativo Android. Também guardo um perfil de usuário no Firebase, que contém a ID do usuário e opções extras que o usuário pode atualizar no aplicativo Android.
Na inicialização, o aplicativo verifica a autenticação e a autenticação. Ele recarrega o perfil do usuário (no Firebase) para atualizar minha userInstance no aplicativo.
O Firebase está definido como compatível com offline no nível do aplicativo. O userInstance POJO é sincronizado com o Firebase no log e para para ser sincronizado no log.
Eu tenho um parâmetro especial, no meu perfil de usuário, que posso alterar (como administrador).
Sempre que o atualizo no console do Firebase, ele é substituído pelo valor anterior quando o aplicativo é iniciado novamente.
Como isso pode acontecer?
BTW: 1 / Com base em qual mecanismo os dados são mesclados, se vários clientes tiverem valores locais diferentes?
Aqui está o código mais simples, onde tentei reproduzir o erro. :
MyApplication.java
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Firebase.setAndroidContext(this);
Firebase.getDefaultConfig().setLogLevel(Logger.Level.DEBUG);
Firebase.getDefaultConfig().setPersistenceEnabled(true);
}
}
Atividade principal
public class MainActivity extends AppCompatActivity {
Firebase ref;
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ref = new Firebase("https://millezim-test.firebaseIO.com").child("user");
ref.keepSynced(true);
Button br = (Button) findViewById(R.id.b_read);
Button bs = (Button) findViewById(R.id.b_save);
final TextView tv_r = (TextView) findViewById(R.id.tv_value_toread);
final EditText tv_s = (EditText) findViewById(R.id.tv_value_tosave);
user = new User();
bs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!tv_s.getText().toString().equalsIgnoreCase(""))
user.setAge(Integer.valueOf(tv_s.getText().toString()));
ref.setValue(user);
}
});
br.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue(User.class);
if (u != null)
tv_r.setText(String.valueOf(u.getAge()));
else
tv_r.setText("Bad Value");
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
});
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
User u = dataSnapshot.getValue(User.class);
u.setCounter(u.getCounter() + 1);
user = u;
saveUser();
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
public void saveUser() {
ref.setValue(user);
}
}
Se você acabou de alterar um valor no aplicativo, o contador aumenta até o aplicativo parar: isso é normal. Mas o que é vertente é a passagem da idade do antigo para o novo e depois para o antigo ciclicamente, sem parar.
E sinto esse comportamento no meu aplicativo, sem o cíclico, pois não tenho um contador, mas não consigo alterar um parâmetro no cliente administrador, sempre recupero o valor anterior armazenado no celular.
Eu apenas Auth, atualizo meu UserInstance com AuthData + o usuário busca no Firebase (provavelmente os dados armazenados em cache) e, em seguida, salvo o usuário atualizado no Firebase (como posso obter o novo AuthData e normalmente consigo o usuário mais recente) Firebase)
2 / Neste exemplo simples, vi que, se eu ler o valor no início, ele buscará os dados armazenados em cache no aplicativo. Como posso forçar a ter dados online?