Unhandled promise rejection: Expected URL scheme 'http' or 'https' but was 'file'

const geometry = new THREE.BoxBufferGeometry(1, 1, 1);
const textureLoader = new THREE.TextureLoader()
const dummyURL = "https://images.unsplash.com/photo-1579546929662-711aa81148cf?ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8Z3JhZGllbnR8ZW58MHx8MHx8&ixlib=rb-1.2.1&w=1000&q=80"
const dummyTexture = textureLoader.load(dummyURL)
const textureMaterial = new THREE.MeshBasicMaterial({
     map: dummyTexture
})
let cube = new THREE.Mesh(geometry, textureMaterial);  

I am using the above code to load texture from a URL in a React Native application (helpful reference)

The problem is that when I change the value of the dummyURL variable to the URI of a local file (png or jpg) saved in the phone’s gallery, it is not loading that particular file as a texture. It gives this warning in yellow -

“Unhandled promise rejection: Expected URL scheme ‘http’ or ‘https’ but was ‘file’”

I changed the above code a bit👇

    const textureLoader = new TextureLoader()
    const textureURL = "file:///data/user/the_full_uri_to_the_local_file.png" 
   
    let textureMaterial = new MeshNormalMaterial()

    textureLoader.load(
      textureURL,
      function(texture){
        console.log("Texture loaded successfully")
        const dummyTexture = textureLoader.load(textureURL)
        textureMaterial = new MeshBasicMaterial({
          map: dummyTexture
        })
        
      },
      function(xhr){
        console.log((xhr.loaded/xhr.total * 100)+"% loaded")
      },
      function(err){
        console.log("An error happened--->"+err)
      }
    )

    const cube = new Mesh(geometry, textureMaterial);  

And after running the application on my phone the console screen doesn’t show any of the console log statements given above. Ideally atleast one of those statements should show up. Why so?

Also, it is mentioned in the TextureLoader docs that the load function takes in a url parameter which can also be a Data URI. So it should work.

P.S - The value of textureURL variable is basically fetched through an image picker library, but for convenience sake I have provided the textureURI to the file in string instead of the code that implements the logic for letting the user pick up an image from the library because it doesn’t really play a big part in this discussion.

You actually hit a security constraint. Loading from file is not supported. More information in the following guide: three.js docs

The common solution for this issue is to host your app (and media content) on local web server and refer with HTTP(S) to your assets.

2 Likes