2016-04-16 10 views
0

Ich habe versucht, Einfügen von Daten innerhalb Zeitstempel etwa 10 Sekunden, da mein Programmstart zu ermöglichen, habe ich die folgende DatenstrukturFirebase ermöglichen Einsetzen in Timestamp

  • Daten
    • Artikel
    • Zeit
      • Zeit

das Programm beim Start ich den aktuellen Zeitstempel, wie folgend

in time speichern
firebaseRef.child("time").setValue(ServerValue.TIMESTAMP, listener); 
firebaseRef.child("time").addListenerForSingleValueEvent(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot dataSnapshot) { 
     Long timestamp = (Long) dataSnapshot.getValue(); 
     System.out.println(timestamp); 

     HashMap<String, Object> map = new HashMap<>(); 
     map.put("time", timestamp); 
     firebaseRef.child("time").setValue(map, listener); 
    } 

    @Override 
    public void onCancelled(FirebaseError error) { 
    } 
}); 

und ich machte die folgende Sicherheitsregel

"items": { 
    ".read": true, 
    ".write": true, 
    ".validate": "newData.parent().child('time').child('time').val() + 10000 >= now" 
} 

Aber es hat funktioniert und ich nicht Erlaubnis verweigert. Was ist falsch an meiner Regel?

+0

Worauf deutet 'fireBaseRef' hin? –

+0

Ihre Sicherheitsregel besagt, dass die Zeit größer sein muss als jetzt + 10000, aber Firebase.ServerValue.TIMESTAMP wird jetzt auf diesen Wert gesetzt. – Kato

+0

@FrankvanPuffelen firebaseRef es ist der Referenz-Code meiner App 'Firebase firebaseRef = neuer Firebase (" meine App-URL ")' – SaNtoRiaN

Antwort

2

Eines der Probleme ist sicher, dass Sie die Initialisierung mit:

firebaseRef.child("time").setValue(ServerValue.TIMESTAMP, listener); 

Dies setzt den Wert von time auf eine lange.

{ 
    "time": 1460776272703 
} 

Aber dann:

HashMap<String, Object> map = new HashMap<>(); 
map.put("time", timestamp); 
ref.child("time").setValue(map, listener); 

Sie setValue() auf time dann in einer Karte mit einem Aufruf time Schlüssel übergeben wird, so am Ende time/time zu schreiben.

{ 
    "time": { 
    "time": 1460776272703 
    } 
} 

Auch wenn dies beabsichtigt ist, scheint es eine schlechte Idee, die Datenstruktur so zu ändern. Zum Beispiel im Simulator lief in ich schnell eine Fehlermeldung wie folgt aus:

Type Error: + only operates on numbers and strings.

Weil es ein JSON-Objekt (/time im zweiten Schnipsel oben) als numerischer Wert zu bewerten versuchte.

Mein Arbeits Schnipsel ist einfacher:

Firebase ref = new Firebase("https://stackoverflow.firebaseio.com/36658910"); 
    ref.child("time").setValue(ServerValue.TIMESTAMP, listener); 
    /*ref.child("time").addListenerForSingleValueEvent(new ValueEventListener() { 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      System.out.println(dataSnapshot.getValue()); 
      Long timestamp = (Long) dataSnapshot.getValue(); 
      System.out.println(timestamp); 
      dataSnapshot.getRef().setValue(timestamp); 
     } 
     public void onCancelled(FirebaseError error) { } 
    });*/ 

ich es wie dieser so Test ausführen, um die Lage der Aussaat und dann mache ich einen weiteren Lauf, wo ich die anfängliche setValue() deaktivieren und den Hörer ermöglichen, Updates zu testen.

Die entsprechenden Sicherheitsregeln:

"time": { 
    ".write": true, 
    ".validate": "(!data.exists() && newData.val() == now) || newData.child('time').val() + 100000 >= now" 
} 

Sie werden bemerken, dass ich für das Schreiben der Anfangswert separaten Fälle (die mit ServerValue.TIMESTAMP getan werden muss now übereinstimmen) und die Updates (die innerhalb von 100 sein muss Sekunden nach dem vorherigen Schreiben).

+0

Danke für Ihre Antwort. Ich kenne das Problem nicht, aber 'firebaseRef.child (" time "). SetValue (ServerValue.TIMESTAMP, listener)' setzt keinen Wert, ich habe es viel probiert, deshalb musste ich das speichern Zeit mich selbst. Ich nehme an, 'now' bezieht sich auf die aktuelle Zeit auf dem Server und der Wert der Zeit bezieht sich auf meine Programmstartzeit also. Wenn ich ein Element einfüge, vergleiche ich den Zeitwert mit 'now', um sicherzustellen, dass der Unterschied innerhalb bestimmter Millisekunden liegt, aber das funktioniert auch nicht. Vielleicht ist es meine Schuld und ich missverstand den Zeitstempel und 'now'. – SaNtoRiaN

+0

Ihr initial 'setValue()' schlägt aus mehreren Gründen fehl. Sie haben eine 'time/time'-Verschachtelung und können den Anfangswert nicht setzen. Meine Sicherheitsregeln und der obige Code funktionieren. Probieren Sie sie aus und dann sehen Sie, was ich von Ihrem geändert habe. –

+0

Vielen Dank :) – SaNtoRiaN