react-native-firebase icon indicating copy to clipboard operation
react-native-firebase copied to clipboard

loadBundle() Error: [firestore/unknown] Unknown error or an error from a different error domain.

Open anija opened this issue 2 years ago • 3 comments

I'm trying to use bundles following the documentation:

const response = await fetch('https://api.example.com/bundles/latest-stories');
const bundle = await response.text();
await firestore().loadBundle(bundle);

loadBundle raise the error [firestore/unknown] Unknown error or an error from a different error domain.. The bundle content seems correct. The endpoint for the bundle creation it's already used by the website in react, and it's working, this is why I'm excluding a backend problem.

anija avatar Apr 28 '22 12:04 anija

Hi @anija ! Thanks for trying out a brand new feature, normally I'd say "I'm pretty sure this is a project issue" because most of the features here have been well-tested live but honestly you might be the first to use this feature since it was just implemented and released. So this may take some effort to make work, or it might be something simple - I can't predict

That said, you can see where we exercise this in our e2e code, which I have personally tested locally and worked through carefully during the PR process with @bernard-kms on #6199 and it did all seem to work.

Bernard was originally doing the fetch from our API over the network as you mention and that seemed to work for them. Now we define it statically to reduce network failures during testing, but it's just the result of the fetch: https://github.com/invertase/react-native-firebase/blob/a799c14382e2448e32428e4a83bc286533e4dd35/packages/firestore/e2e/helpers.js#L59

We do the loadBundle tests here: https://github.com/invertase/react-native-firebase/blob/main/packages/firestore/e2e/Bundle/loadBundle.e2e.js

...as well as before each test here in order to prep the query checks: https://github.com/invertase/react-native-firebase/blob/a799c14382e2448e32428e4a83bc286533e4dd35/packages/firestore/e2e/Bundle/namedQuery.e2e.js#L22

They seem to work? Locally, I was able to make them fail actually (on purpose by injecting errors) and work, so they do seem like they are really working and not just false-positive.

So I want to say this is a project-specific problem, but I think it will end up being "We need to document something a lot better" because there is some failure mode we don't understand.

You can try running our e2e test suite locally, it's all documented here https://github.com/invertase/react-native-firebase/blob/main/tests/README.md and if you are already using firebase you'll have the tools you need I think already installed so it shouldn't be too bad to try. If that works, then we know the code can work and we just have to figure out why it's not working for you?

mikehardy avatar Apr 28 '22 13:04 mikehardy

Hi! As you said the bundle endpoint works as expected with the web SDK, I'm guessing there might be a problem decoding the response. The Firebase Web SDK allows you to load bundle content via a ReadableStream or a decoded string, but the current RNFB implementation only accepts UTF-8 decoded string content.

Having said that, I think we need a more documentation or implementation improvement at least in this area, as we try to mirror the interface of the Web SDK as much as possible.

kmsbernard avatar Apr 28 '22 15:04 kmsbernard

Hmm - you could be on to something there. Even if the test harness / test fixture in our e2e tests were were hitting the API instead of the static bundle from the API, the execution environment there is using the react-native javascript debugging interface - so the fetch would be running off-device, in a node instance, so does not necessarily represent what it is like to fetch + try to load a bundle from an API in a real app. These differences could be important and are probably the source of issues.

@anija can you confirm what sort of encoding the string has? I'm not sure how exactly to do that myself, but trying different ways of passing the bundle content in might be useful. Additionally, one thing I do frequently when troubleshooting stuff like this is to reach directly in to node_modules and add logging statements all over - in the javascript and in the native code, with information about all parameters passed into an API call going to another layer, and all results (or errors) coming out. That helps localize things then I start playing with the parameters going in - sending it fixed / known good values to see it work, then going from there.

That usually does take some time, but frequently less time then it takes for a comment to go on github and get a reply later etc so might be an efficient way to move this forward

mikehardy avatar Apr 28 '22 17:04 mikehardy

Just if this helps anyone else, this error can occur if you are trying to load a bundle from an endpoint that serves data from a firebase project other than what your app is configured to point against (e.g. you're running against a staging project with your debug build and fetching from a production REST endpoint).

wneild avatar Oct 05 '22 16:10 wneild

Hello 👋, to help manage issues we automatically close stale issues.

This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?

This issue will be closed in 15 days if no further activity occurs.

Thank you for your contributions.

github-actions[bot] avatar Dec 05 '22 19:12 github-actions[bot]

For me, if I use the select method for the query on the server side, I got the loadBundle error on the client side

export const postBundle = https.onRequest(async (request, response) => {
    const querySnapshot = db.collection('posts')
        .select('field1', 'field2') // <= THIS CAUSES ERROR
        .get();
    const bundleBuffer = db.bundle('mybundle')
        .add('posts-query', querySnapshot)
        .build();
    response.set('Cache-Control', 'public, max-age=86400, s-maxage=86400');
    response.end(bundleBuffer);
});
const { data } = await axios.get('https://[region]-[projectid].cloudfunctions.net/postBundle');
await db.loadBundle(data); <= [Error: [firestore/unknown] Unknown error or an error from a different error domain.]

If you check the XCode console, you'll see this error message

[FirebaseFirestore][I-FST000001] Failed to GetNextElement() from bundle with error Queries with 'select' statements are not supported in bundles

I guess the bundled data is static, not something that you can arbitrarily select fields, so they don't support. However, when you bundle something for publicly caching, you would need to filter out some sensitive and not required fields to keep the privacy and reduce the amount of data. So l have to loop through the querysnapshot, dangerously mutate it by deleting some fields from the document data, and then bundle querysnapshot.

anhnch avatar Mar 21 '23 07:03 anhnch