Meteor-Community-Packages / Meteor-CollectionFS

Reactive file manager for Meteor
MIT License
1.05k stars 237 forks source link

Images 404ing when using Cordova #425

Open IstoraMandiri opened 9 years ago

IstoraMandiri commented 9 years ago

I'm not sure if this problem is specific to CFS, but when using Cordova + iOS Sim, CFS requests are getting 404d, I think due to the 'random' port number that either Cordova or Meteor is using (and I'm not sure why it does this).

If I run meteor run ios -p 127.0.0.1:3000, go to localhost:3000, the app works fine as expected with images loading correctly. In iOS Simulator, however, most of the app works fine, /public assets load properly, but CFS files return with 404. I'm using GridFS.

Inspector reveals that the cordova version is using some port other than 3000, and I can also visit 127.0.0.1:[cordova-port] locally in chrome, which has the same 404 issues.

404: URL:http://10.0.1.15:44564/cfs/files/[col]/tYGzBPHRD4vEPcwHc/master114811-4027-6t2q73.jpeg?token=eyJhdXRoVG9rZW4iOiIifQ%3D%3D&store=thumb

meteor run ios -p 127.0.0.1:3000                                                                                                                                                                                                                                                 
[[[[[ ~/git/project-name ]]]]]

=> Started proxy.
=> Started MongoDB.
=> Started Cordova (ios).
=> GraphicsMagick found
(ios) objc[13090]: Class AXEmojiUtilities is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/usr/lib/libAXSpeechManager.dylib. One of the two will be used. Which one is undefined.
(ios) Cannot find executable for CFBundle 0xa868dd0 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/AccessibilityBundles/CertUIFramework.axbundle> (not loaded)
(ios) Cannot find executable for CFBundle 0xa88dac0 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk/System/Library/AccessibilityBundles/GeoServices.axbundle> (not loaded)
(ios) Multi-tasking -> Device: YES, App: YES
(ios) Unlimited access to network resources
(ios)
(ios)
(ios) Started backup to iCloud! Please be careful.
(ios) Your application might rejected by Apple if you store too much data.
(ios) For more information please read "iOS Data Storage Guidelines"
(ios) You could find it at the following address https://developer.apple.com/icloud/documentation/data-storage/ .
(ios)
(ios) [CDVTimer][file] 1.143992ms
(ios) [CDVTimer][statusbar] 12.795985ms
(ios) [CDVTimer][TotalPluginStartup] 16.766965ms
(ios) Resetting plugins due to page load.
(ios) Finished load of: file:///Users/chris/Library/Application%20Support/iPhone%20Simulator/7.0.3/Applications/0C6561BB-AAF6-437B-8CED-BC0FD780E181/library.app/www/index.html
(ios) No new versions saved to disk.
(ios) Starting the server on port 44564
(ios) Setting document root: /Users/chris/Library/Application Support/iPhone Simulator/7.0.3/Applications/0C6561BB-AAF6-437B-8CED-BC0FD780E181/library.app/www/application
(ios) HTTPServer: Started HTTP server on port 44564
(ios) Started httpd on port 44564
(ios) addresses: {
(ios)     "en0/ipv4" = "10.0.1.15";
(ios)     "en0/ipv6" = "xxx";
(ios)     "en4/ipv4" = "10.0.1.2";
(ios)     "en4/ipv6" = "xxx";
(ios)     "ham0/ipv4" = "25.53.23.204";
(ios)     "ham0/ipv6" = "xxx";
(ios)     "lo0/ipv4" = "127.0.0.1";
(ios)     "lo0/ipv6" = "fe80::1";
(ios) }
(ios) Resetting plugins due to page load.
=> Started your app.

=> App running at: http://127.0.0.1:3000/
(ios) Finished load of: http://10.0.1.15:44564/
(ios) failed [404]
monocursive commented 9 years ago

Same problem here I guess. On Android

I20140916-20:42:21.577(2) (android:http://192.168.1.69:12419/packages/cfs_access-point.js:268) failed [404] Error 404, file not found.

gabrielhpugliese commented 9 years ago

I'm not using CollectionFS and found the same issue on Android. Came here from Google.

arboleya commented 9 years ago

Did anyone find any solution for this?

arboleya commented 9 years ago

Well, I realized the /cfs/* route used to fetch the images only exists on the server, but not on the client which is the only part of your meteor app that gets packed with Cordova.

So what I did was to use absolute urls for all image sources, forcing them all to go to server instead the local http://meteor.local application that lives inside the Cordova packed app.

Something like this..

UI.registerHelper('root_url', function(){
  return __meteor_runtime_config__.ROOT_URL.slice(0,-1);
});

UI.registerHelper('find_image', function(image_id){
  return Images.findOne({_id: image_id});
});
<template name='ShowImage'>
  {{#with find_image this.image_id}}
    <img src="{{root_url}}{{this.url}}"/>
  {{/with}}
</template>
devdudeio commented 9 years ago

I have the same problem on any iOS Device. Its not working on my mobile devices when using an relative path. @arboleya´s solution works but I would like to get the images from the client device. download from the server is too slow. any idea how to get them with cordova/meteor builds?

tlundgren commented 9 years ago

@arboleya 's solution works beatifully. thanks!

derwaldgeist commented 9 years ago

@arboleya: Thanks for the hint to the meteor_runtime_config.ROOT_URL I'm wondering why you added the .slice(0, -1). In Cordova with a local server, this cut away part of the :3000 port.

EDIT: Seems as if ROOT_URL ends on "/" in the desktop browser, but does not in iOS Cordova. Hence, I replaced the line with:

return __meteor_runtime_config__.ROOT_URL.replace(/\/$/,'');
devdudeio commented 9 years ago

maybe I´m wrong but is this bypassing the image mongoDB Collection, isn´t it? it looks like I´m requesting the images directly from the server via URL and not from the local image collection on the client (iOS/Android Device).

IstoraMandiri commented 9 years ago

AFAIK the client version of mongo isn't actually sent any of the binary data; CFS will always use the server for serving images.

You might be able to workaround this by using a cache manifest in your Cordova app to cache the images locally, though.

derwaldgeist commented 9 years ago

I don't think MongoDB is the problem here; the GridFS itself seems to be working, as the URLs can be retrieved successfully like on the desktop browser. It just seems as if the /cfs/... route that CFS is using isn't supported on the iOS device, where every request is channeled through the meteor.local pseudo server which obviously is not aware of this /cfs route. Maybe there's a way for CFS to hook into that routing, just as other routers do? I've now workarounded this using @arboleya's hack to route to the actual meteor server instead. But this is sub-optimal, as there is no latency compensation and no offline support with this approach.