Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Image is not defined" error when using Cloud Firestore from React Native app #183

Closed
mackenziemance opened this issue Oct 4, 2017 · 22 comments · Fixed by #304
Closed

Comments

@mackenziemance
Copy link

mackenziemance commented Oct 4, 2017

[REQUIRED] Describe your environment

react-native: 0.47.2,
Firebase SDK version: 4.5.0
Firebase Product: cloud firestore_ (auth, database, storage, etc)

[REQUIRED] Describe the problem

Around 2 - 3 mins after I query firestore I'm getting a Image reference error

Code to reproduce:

db.collection("users").get().then((snap)=>{
snap.forEach((doc)=>{
console.log(doc.data())
})
})

simulator screen shot - iphone 6 - 2017-10-04 at 16 46 02

console outputs
screen shot 2017-10-04 at 7 03 12 pm
when signing out of auth

@mikelehen
Copy link
Contributor

Thanks @mackenziemance. We have not invested in making the Firestore Web SDK work in React Native's javascript environment. To be honest, I'm not sure how much effort this will require.

Out of curiosity, have you considered using react-native-firebase? It supports Firestore (https://invertase.io/react-native-firebase/#/modules/firestore) and is built on top of the Android and iOS SDKs instead of the Web SDK so should be a bit more reliable.

@mikelehen
Copy link
Contributor

Also, for curiosity's sake, does everything else seem to work fine until you get that error? Do queries and writes to Cloud Firestore successfully complete, etc.?

@mackenziemance
Copy link
Author

Thanks for the support @mikelehen i guess since the rtdb always worked perf with this sdk I never took a look at the rn package, now I’ll switch. I’ve got docs, listend to changes, wrote with set/update/batch/transaction all seem to work. The only issues I ran into were the console.errors.

@mikelehen
Copy link
Contributor

Cool, thanks for the info. I've started a discussion internally to see if we can get the 'Image is not defined' error fixed in the future.

@ricklove
Copy link

I am running into this error also. I get random Image reference errors after a period. Also, I get them any time I try to change the user.

The reason for using the WebSDK in react native is because of Expo. Expo allows building react-native projects (without an XCode or an Android project) and deploying them to the Expo app for testing on device. They do this by reusing their native build which already has selected plugins for react-native.

However, this framework only works with pure javascript (no plugins). So in order to use the Firebase native SDK, it would require "ejecting" from Expo which means generating your own XCode and Android projects and managing the plugins yourself (which loses all the primary benefits of managed plugins that Expo offers).

For me, the benefit of Expo is primary: being able to create a new app, publish it, and send a link to my client in a few hours.

Of course, Expo makes a perfect marriage with Firebase in general (with both I can build an entire app in a day).

I think Firestore is great, but it would be easier for me to roll my own backend then to replace Expo's excellent deployability at this time. For a temporary workaround, I'll probably use Cloud Functions to wrap my Firestore access, but I haven't figured out real time updates yet (and I lose the user based security model of Firestore)...

So, I hope that explains our situation and why it is worth supporting this scenario: there is a large potential audience segment who could fall under this category.

@ricklove
Copy link

ricklove commented Oct 13, 2017

Partial Workaround

I found that calling app.delete() and then recreating the app worked to allow me to change users:

    // First time
    let app = firebase.initializeApp(C.firebaseConfig);
    let firestore = firebase.firestore(app);
    let auth = firebase.auth(app);

    ...
    // Before Change User
    await app.delete();
    app = firebase.initializeApp(C.firebaseConfig);
    firestore = firebase.firestore(app);
    auth = firebase.auth(app);

@mikelehen
Copy link
Contributor

[Reopening since hopefully we can fix this at some point]

As another workaround, you could try just creating a global 'Image' constructor. I haven't tried it, but I'd be curious if:

global.Image = function() { }

would avoid the reported crash.

@mikelehen mikelehen reopened this Oct 13, 2017
@ricklove
Copy link

ricklove commented Oct 13, 2017

@mikelehen I tried doing something like that (creating a fake Image class), but when I checked for Image in my code, it existed.

I didn't know if webworkers or something was providing a different global context where Image did not exist, but my attempts to do that didn't seem to accomplish much.

I'm also not entirely sure the purpose of using Image in the source code. I assume it is just a hacky way to make a get request (and maybe bypass CORS or something)?

@mikelehen
Copy link
Contributor

Hrm, strange. I'm pretty sure the consuming code is just looking for a global 'Image' variable. FWIW- this is the code: https://github.com/google/closure-library/blob/master/closure/goog/labs/net/webchannel/channelrequest.js#L834

And your guess about a hacky way to make a get request is basically correct. I think it's trying to make a GET request that will succeed even if the browser page is being closed (it's trying to clean up the backend connection).

I've had a discussion with the webchannel maintainer and we believe we can fix it to just do a normal XHR if 'Image' does not exist. But it will take a while for that fix to happen and make it to the Firestore SDK I'm afraid.

@mikelehen mikelehen changed the title Image reference error "Image is not defined" error when using Cloud Firestore from React Native app Oct 13, 2017
@ricklove
Copy link

@mikelehen You are correct. I made a mistake the first time I checked for the Image.

Your idea to provide an Image implementation seems to work well. Here is my implementation in Typescript and it prevents the Image Reference exception (and it should do the expected Get request also and call onload when done).

So I believe this is a complete workaround.

Workaround

The [Missing] Image class was used to execute a get request and this workaround uses the fetch method to do the same.

import * as firebase from 'firebase';
// Required for Side Effects
import 'firebase/firestore';
import 'firebase/auth';

declare var global: any;

class FakeImage {
    static ensureImageExists() {
        if (!global.Image) {
            global.Image = FakeImage;
        }
    }

    _isLoaded = false;
    _callbacks: (() => void)[] = [];

    set src(url: string) {
        this._isLoaded = false;
        this.load(url);
    }

    load = async (url: string) => {
        await fetch(url);
        this._callbacks.forEach(x => x());
        this._isLoaded = true;
    };

    onload(callback: () => void) {
        if (this._isLoaded) { callback(); }
        this._callbacks.push(callback);
    }
}

FakeImage.ensureImageExists();

const app = firebase.initializeApp({
    // INSERT SETTINGS
});

firebase.firestore.setLogLevel('debug');
const firestore = firebase.firestore(app);
const auth = firebase.auth(app);

@mikelehen
Copy link
Contributor

Nice! Thank you for contributing this! 👍 👍 👍

@felipecocco
Copy link

@ricklove Thank you so much for the implementation of the workaround -- worked great for me!

@mikelehen I just wanted to echo the calls for some investment into looking if a proper fix is possible. Firebase WebSDK with Expo is fantastic, and with the added power and flexibility of Firestore, the gains are even more significant. Certainly no better way to get started developing mobile apps today.

@mikelehen
Copy link
Contributor

Thanks for the feedback. There has been work done on the underlying webchannel issue internally and I'm hoping we'll get the fix into the firebase SDK in the next 2-3 weeks.

@PeterBocan
Copy link

Thank you guys! I was clueless for like 2 days what's going on...

@rexjrs
Copy link

rexjrs commented Nov 7, 2017

How can I get the workaround to work without Typescript? I am using pure javascript.

@rexjrs
Copy link

rexjrs commented Nov 9, 2017

How long does it usually take to move to the next version that includes this fix on NPM?

@firebase firebase deleted a comment Nov 9, 2017
@firebase firebase deleted a comment Nov 9, 2017
@mikelehen
Copy link
Contributor

@rexjrs If things go smoothly, I believe the release should go out today. You can keep an eye out on https://firebase.google.com/support/release-notes/js for the update... I'll also try to remember to leave a comment once the release is out.

@harisvsulaiman
Copy link

@mikelehen But firesstore doesnt even seem to work with android. see #283

@mikelehen
Copy link
Contributor

@harisvsulaiman Thanks for the note. That is unfortunate! I've marked that bug as help-wanted and added a comment soliciting more information as I'm not sure when one of us will have cycles to reproduce and debug the issue so I'm hoping somebody from the community can perhaps help.

@ghost
Copy link

ghost commented Oct 3, 2018

I am still getting this issue with RN version 0.55.3, firebase@^5.5.2.

https://firebase.google.com/support/release-notes/js, version 4.6.2 mentions the fix was included.

@mikelehen was the fix tested on RN? If so, what version?

Thanks.

@mikelehen
Copy link
Contributor

Yes, that issue was fixed and verified and I haven't heard subsequent reports of it. If you are hitting it (or something similar), please file a new issue with as much detail as you can include (what versions of dependencies you are using, your code, the exact error you are getting, etc.).

@ghost
Copy link

ghost commented Oct 3, 2018

Ok, have reposted:
#1279

@firebase firebase locked and limited conversation to collaborators Oct 26, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants