Firebase如何与共享数据同步?

Ant*_*ony 4 java database android synchronization firebase

我使用Firebase来处理Android应用的Auth主题.我还在Firebase上保存了一个用户配置文件,其中包含用户ID和用户可以在Android应用中更新的额外选项.

启动时,应用程序会检查身份验证和身份验证.它重新加载用户配置文件(在Firebase上),然后在应用程序上更新我的userInstance.

Firebase在应用级别设置为离线功能.userInstance POJO在日志时与Firebase同步,并在unlog时停止同步.

我有一个特殊的参数,在我的用户配置文件中,我可以更改(作为管理员).

每次我在Firebase控制台上更新它时,它会在应用程序重新启动时替换为之前的值.

怎么会发生这种情况?

BTW:1 /如果多个客户端有不同的本地值,基于合并数据的机制?

这是更简单的代码,我试图重现错误.:

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);


    }
}
Run Code Online (Sandbox Code Playgroud)

主要活动

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您只是在应用程序中更改了值,那么计数器包含直到应用程序停止:这是正常的.但是什么是股票是从旧到新的循环而不是停止的循环.

在此输入图像描述

我觉得我的应用程序中的行为,没有循环,因为我没有计数器,但我无法更改管理客户端中的参数,我总是收回存储在移动设备中的先前值.

我只是Auth,然后我用AuthData +用户从Firebase中获取我的UserInstance(可能是缓存的数据),然后我在Firebase下保存更新的用户(因为我可能有新的AuthData,我通常从最新的用户获取火力地堡)

2 /在这个简单的例子中,我看到如果我在start时读取值,它会获取应用程序中缓存的数据.我如何强制拥有在线数据?

Fra*_*len 10

问题来自于您正在使用具有单值事件侦听器的磁盘持久性.当你这样做时:

ref.addListenerForSingleValueEvent(new ValueEventListener() {...
Run Code Online (Sandbox Code Playgroud)

您要求该位置的单个值(在您的情况下为用户).如果Firebase在其本地缓存中具有该位置的值,则会立即触发该值.

解决此问题的最佳方法是不使用单值侦听器,而是使用常规事件侦听器.这样,您将获得两个事件:一个用于缓存版本,另一个用于从服务器返回的版本(如果不同).

唯一的选择是不使用Firebase的磁盘持久性.没有它,就不会有重新启动时读取数据的本地缓存.

在Firebase邮件列表上有关于此组合的一些讨论.这是一个:https://groups.google.com/forum/#!msg/firebase-talk/ptTtEyBDKls/XbNKD_K8CQAJ