We are aware of the issue with the badge emails resending to everyone, we apologise for the inconvenience - learn more here.
Forum Discussion
latimba
6 years agoExplorer | Level 3
longpoll workflow / flowchart / advice how to do it right
Hello Dropbox API team, I built an app that loads and saves information from a single text file in Dropbox. That app could be used from several devices, mobile and desktop, and therefore has to det...
Greg-DB
6 years agoDropbox Staff
Using the /2/files/list_folder/longpoll endpoint, filesListFolderLongpoll in the JavaScript SDK, is the right way to monitor for changes in a connected Dropbox account with low latency from a client-side application.
I don't believe we have a particular example or flowchart that would cover this use case very well, but we'll be happy to help with your questions.
Overall, it sounds like one part you're missing though is that you are using filesGetMetadata to get the file metadata each time, and are perhaps also getting the "latest" cursor using filesListFolderGetLatestCursor each time, instead of making use of listFolder and listFolderContinue.
If you use listFolder and listFolderContinue, you can keep track of changes over time, without the risk of missing anything, e.g., due to race conditions. For example, a typical flow would look like this:
- Call listFolder and listFolderContinue until FilesListFolderResult.has_more is false to get all of the current file/folder state and save the last cursor (or use filesListFolderGetLatestCursor for this initial step if that makes sense for your use case).
- Call filesListFolderLongpoll with that cursor to monitor for changes.
- When there are changes, call listFolderContinue to retrieve just the changes since you last called it, based on the cursor.
- (and repeat the previous two steps)
To answer your specific questions though:
-what is the best way to handle longpoll if an error is returned, either when getting the latest cursor or during the longpoll? An example would be a lack of internet connection. Currently, I postpone the next longpoll for 30 seconds (and in the case of a backoff response, for the seconds which are requested). Is that a good idea, or should I handle errors differently, perhaps depending on the error I get?
Yes, you'll likely want to handle each kind of error differently. For a network-level error like you describe, you'll probably just want to wait and try again, and perhaps notify the user of the issue in the UI, if applicable.
For an API-level issue, it depends on the error returned. For example, FilesListFolderLongpollError.reset means your cursor is invalid, so you'll need to start over to get a new one.
-supposed that 30 seconds delay is a good idea: In those 30 seconds (or it could be much longer, like on a plane), the file in Dropbox could have been changed by another client. If the longpoll resumes, the cursor has changed without the app knowing about it, right? Should I also store and watch the last cursor locally, so that I know something changed? Or use a different method?
Your app should store the last cursor it received. As long as it passes that cursor back to listFolderContinue, the Dropbox API will return all of the changes that the app needs to know about since that cursor was returned.
-it gets more complicated when I save / push updates to that file in rapid succession (which I do): While the app is busy with handling a change from the longpoll, the next change could be on the way and I'm not sure it gets detected between the one longpoll exiting with a change response and the next longpoll not yet being established.
Using the flow described above will help avoid any such race conditions. You can also use the 'rev' or 'content_hash' values to determine if you have the latest file data or not.
Hope this helps!
- marimba6 years agoNew member | Level 2
Dear Greg,
thank you very much for that extensive answer, has been very helpful!
- elsigh5 years agoHelpful | Level 5
I wonder if one thing not covered in this flow is, say, if the folder name is changed in Dropbox.. Maybe that's why they (and I) want to call `filesGetMetadata` as well on the folder in addition each time. Is there another/more efficient way to catch and handle that from the client side? I will double check that the longpoll doesn't return changes to the folder itself.. (it looks very `entities` focused)
- Greg-DB5 years agoDropbox Staff
elsigh Renaming a file or folder will be reflected by listFolder/listFolderContinue as a deletion of the item at the original path, and then an addition of the item at the new path.
The file ID doesn't change when renaming an item in Dropbox though, so tracking that value is the best what to correlate these.
- elsigh5 years agoHelpful | Level 5
Hey Greg-DB - ok that's great to know. I haven't gotten to testing renaming/deletion so I'll look out for that. But does that cover the folder being polled? e.g. if I'm polling a folder A and a user goes and renames folder A to folder B I would catch that somewhere?
I've been implementing as you suggested here but I'm wondering about two scenarios I'm seeing.
In one case I'm receiving a response with `changes: false` - I'm guessing in this case I should start the poll again with the same cursor?
In another case it seems that I'm getting `changes: true` so I subsequently call listFolderContinue with the cursor but then get a response that has `entries: []` but does come back with a new cursor.. in other words it seems like I'm not actually getting any changes so I wonder what's going on there? This pattern happens over and over without me making any changes within that folder. Is that expected?
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
5,877 PostsLatest Activity: 23 minutes agoIf you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!