所以我有一个看起来像这样的数据库:
Posts
|
|
|----post_id_1
|
|---post_title = "...."
|---post_body = "...."
|---post_time = "ServerValue.TIME_STAMP"
|
|----post_id_2
|.......
|.......
我想做什么:
我要防止用户阅读帖子发布日期后大于等于一个月的帖子吗?
我尝试过的事情:
我试图通过android使用此方法:
//current time of device
long current_time = System.currentTimeMillis();
//month in millisecond
long month = .....;
if(curent_time - post_time >= month){
//this post was there for a month from the time that it was posted.
}
问题:
如果我使用上述方法,那么如果用户足够聪明,他/她将更改设备输入帖子的时间(不应该)。
问题:
有什么稳定的方法吗?
谢谢。
注意:没有从服务器获取时间戳。
答案 0 :(得分:1)
我将TIME_STAMP存储为UTC并从服务器获取时间,而不是从设备获取时间。
在这种情况下,用户无法更改设备上的时间来修改数据库的输出。
我建议始终将所有日期存储为UTC,并在用户查看日期时将其转换为用户时区。
答案 1 :(得分:1)
我也遇到过同样的问题,我是如何解决这个问题的,现在是对Google进行一次ping操作,然后将该时间存储在Firebase中,这样我就可以比较用户上次执行某项操作的时间,而该时间就是服务器时间并且无法更改。
因此,在我的情况下,每次我的应用程序以onStop
或onDestroy
方法输入时,我都会上载该服务器时间,但是您可以在需要保存到数据库的任何地方使用它。
以下是获取服务器时间的代码段,我使用asyncTask
来获取服务器时间,然后将其发布到我的参考中。只需致电asyncTask
,即可在其中使用服务器时间更新某些内容。
public class getGoogleTime extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet("https://google.com/"));
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.ENGLISH);
dateStr = response.getFirstHeader("Date").getValue();
Date startDate = df.parse(dateStr);
dateStr = String.valueOf(startDate.getTime() / 1000);
long actualTime = java.lang.Long.parseLong(dateStr);
//Here I do something with the Date String
} else {
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (IOException e) {
Log.d("SAF_GTG_Response", e.getMessage());
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
// can use UI thread here
protected void onPostExecute(final Void unused) {
mDatabase.child("Posts").child(post_id_1).child("currentTime").setValue(dateStr, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
Log.d("SAF_GTG_TAG", "Success");
}
});
}
}
要使用Firebase,您可以执行以下操作:
ref = FirebaseDatabase.getInstance().getReference();
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
Long timestamp = (Long) snapshot.getValue();
System.out.println(timestamp);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
ref.setValue(ServerValue.TIMESTAMP);
注意:此方法仅返回UTC时间,您可以将其转换为想要向每个用户显示的时间。
如果您担心网络使用情况,只需ping Google并查看正在使用多少字节和数据包即可。
Pinging google.com [172.217.162.14] with 32 bytes of data:
Reply from 172.217.162.14: bytes=32 time=17ms TTL=53
Reply from 172.217.162.14: bytes=32 time=17ms TTL=53
Reply from 172.217.162.14: bytes=32 time=17ms TTL=53
Reply from 172.217.162.14: bytes=32 time=16ms TTL=53
Ping statistics for 172.217.162.14:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 16ms, Maximum = 17ms, Average = 16ms
从文档中
一个简单的ping命令的带宽消耗,运行一次 每秒,比较小。可能的最小ping数据包 (包括以太网帧标头和IP + ICMP标头,以及 ICMP有效负载的最小32个字节)需要74个字节
约0,074千字节。