Android System.currentTimeMillis() 在 firebase 数据库上的值与在应用程序上生成的值不同 logcat

Android System.currentTimeMillis() value is different on firebase database than generated on app logcat

我正在提交一个在 Firebase 实时数据库上最后一次看到的用户,在 firebase 数据库设置值之前,我正在生成一个带有 System.currentTimeMillis() 时间戳的日志,但是当我将它与 logcat 和数据库时间戳进行比较时它在服务器上提交了不同的时间戳。

查看 logcat 它显示了正确的时间戳,它也应该在服务器上

Disconnect with the firebase server 
Offline Time 5:01 pm 1639308715905

时间戳的 Firebase 实时数据库值

1639308009264

两个值不同,这就是我最后一次看到用户时出错的原因

1639308715905 - App one 
1639308009264 - Server One

我用于记录和在服务器上设置值的代码。

public class MainActivity extends AppCompatActivity {

    public static final String TAG = "Main Activity";
   
    FirebaseDatabase DatabaseInstance;
    DatabaseReference infoConnected;
    



    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "On Resume Running");        
        DatabaseInstance.goOnline();
        
    }


    @Override
    protected void onStop() {
        super.onStop();
        Log.d(TAG, "ON STOP CALLING");
        DatabaseInstance.goOffline();


    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DatabaseInstance = FirebaseDatabase.getInstance(); // Single Instance
        infoConnected = DatabaseInstance.getReference(".info/connected"); // To check firebase connection state
        initialiseOnlineStatus();

        setContentView(R.layout.main);
    }
        



    
    private void initialiseOnlineStatus() {
        final DatabaseReference Online = DatabaseInstance.getReference("Users/" + userID + "/Online");
        final DatabaseReference lastOnline = DatabaseInstance.getReference("Users/" + userID + "/lastSeen");


        infoConnected.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                boolean connected = dataSnapshot.getValue(Boolean.class);

                if (connected) {
                    Online.setValue(Boolean.TRUE);
                    lastOnline.removeValue();

                    Log.d(TAG, "Connected To Firebase Server ");
                } else {
                    Log.d(TAG, "Disconnect with firebase server ");
                    Online.onDisconnect().setValue(Boolean.FALSE);
                    String offlineTime = String.valueOf(System.currentTimeMillis());
                    Log.d(TAG, "Offline Time " + App_Functions.getLocalDeviceTimestamp(Long.parseLong(offlineTime)) + " " + offlineTime); // Get local device time from milliseconds
                    lastOnline.onDisconnect().setValue(offlineTime);
                    
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });


    }



} 

更新: 我注意到上传的最后一个时间戳(由应用程序生成)不是当前时间戳,我真的不明白我最后一次看到的怎么没有更新当前时间戳。请检查 gist 以获取完整代码

我还注意到,在我的 activity 启动时,firebase 函数调用了两次,第一次使用值 boolean connected = dataSnapshot.getValue(Boolean. class); false 而不是 true。因此,使用 false 值,我得到了第一个时间戳,它在 activity onStop 调用时不应更新,而当应用程序调用 onStop 时,它会更新在应用程序启动时首次创建的时间戳。

当您在代码中调用它时:

lastOnline.onDisconnect().setValue(offlineTime);

这会向服务器发送一个文字值,并指示在它检测到客户端已断开连接时写入该值。服务器不知道值的含义,不能对其进行任何更改。

因此,如果在服务器上写入的值与在客户端中记录的值不同,我能想到的唯一原因是您调用 onDisconnect(在其他地方?)也使用了不同的值。

System.currentTimeMillis() 将为您提供模拟器的纪元时间,这意味着无论是模拟器还是 phone 系统时间,它都会给您

我要感谢 @argzdev and @frank 在 github 帮助我。我从@argzdev Github 得到的解决方案:

The reason this doesn't work is because you're trying to set a value after you've already disconnected the connection, it's bound to cause issues.

What you can do is change the logic of how you store the timestamp. Simply store the timestamp BEFORE you sever the connection. There shouldn't be any difference in time, even if there was, it would only be miniscule.

Relevant code:

 @Override
>     protected void onResume() {
>         super.onResume();
>         Log.d(TAG, "On Resume Running");
> 
>         Online.setValue(Boolean.TRUE);
>         lastOnline.removeValue();
>         DatabaseInstance.goOnline();
>     }
> 
> @Override
>     protected void onStop() {
>         super.onStop();
>         Log.d(TAG, "ON STOP CALLING");
> 
>         Online.setValue(Boolean.FALSE);
>         lastOnline.setValue("" + System.currentTimeMillis());
>         DatabaseInstance.goOffline();
>     }
> 

Then you can simply remove the onDisconnect in your ValueEventListener.