2

I have a chat app powered by Firebase, and I'd like to get a timestamp from Firebase before pushing any data.

Specifically, I'd like to get the time that a user pushes the send button for a voice message. I don't actually push the message to Firebase until the upload was successful (so that the audio file is guaranteed to be there when a recipient receives the message). If I were to simply use Firebase.ServerValue.TIMESTAMP, there could be an ordering issue due to different upload durations. (A very short message following a very long one, for example.)

Is there anyway to ping Firebase for a timestamp that I'm not seeing in the docs? Thank you!

3
  • I don't really understand the problem. If you call push() the key will be based on the local time when the user pressed the button. If you use Firebase.ServerValue.TIMESTAMP the value written to the database will be exactly when the data is written to disk. What would the conflict be? Can you capture it in a snippet of code that shows the problem? Commented May 5, 2016 at 14:07
  • Does this help? 1. User pushes "send" 2. Audio file starts uploading. 3. Audio file finishes uploading. 4. In an audioFinishedUploading completion callback, I write the message data to Firebase. I would like a timestamp from the moment the user pushes "send." Commented May 5, 2016 at 14:52
  • I designed it like this so that if the audio upload fails, no message is sent. Commented May 5, 2016 at 14:57

1 Answer 1

3

If you want to separate the click, from the actual writing of the data:

var newItemRef = ref.push(); uploadAudioAndThen(audioFile, function(downloadURL) { newItemRef.set({ url: downloadURL, savedTimestamp: Firebase.ServerValue.TIMESTAMP }); }); 

This does a few things:

  1. it creates a reference for the item item before uploading. This reference will have a push ID based on when the upload started. Nothing is written to the database at this point, but the key of the new location is determined.

  2. it then does the upload and "waits for it" to complete.

  3. in the completion handler of the upload, it writes to the new location it determine in step 1.

  4. it writes the server timestamp at this moment, which is when the upload is finished

So you now have two timestamps. One is when the upload started and is encoded into the key/push id of the new item, the other is when the upload completed and is in the savedTimestamp property.

To get the 3 most recently started uploads that have already completed:

ref.orderByKey().limitToLast(3).on(... 

To get the 3 most recently finished uploads:

ref.orderByChild('savedTimestamp').limitToLast(3).on(... 
Sign up to request clarification or add additional context in comments.

2 Comments

This is an excellent answer, and thank you very much for writing it. I didn't think of using the auto-generated keys as timestamps. While that would solve the problem, our system already uses a custom ID scheme. I wonder if you think just combining the .info time offset with the client timestamp is an acceptable solution here?
Combining the local timestamp with the known offset would get you the same value as is encoded in the push id. :-) So yes, that's equally valid.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.