pocketbase / js-sdk

PocketBase JavaScript SDK
https://www.npmjs.com/package/pocketbase
MIT License
2.17k stars 127 forks source link

Reactive Native and AsyncAuthStore example issue. #249

Closed mez closed 1 year ago

mez commented 1 year ago
import AsyncStorage from '@react-native-async-storage/async-storage';
import PocketBase, { AsyncAuthStore } from 'pocketbase';

const store = new AsyncAuthStore({
    save:    async (serialized) => AsyncStorage.setItem('pb_auth', serialized),
    initial: await AsyncStorage.getItem('pb_auth'),  <== This top level await is not working in react native.
});

const pb = new PocketBase('http://127.0.0.1:8090', store)

Tried this in react native but running into top level await not supported issues. Has anyone tried this and got it working in react native? Any suggestions or an example of getting a store for pocketbase working in react native would be great!

ganigeorgiev commented 1 year ago

I don't think this is specific to PocketBase or the SDK.

From the MDN await docs:

The await operator is used to wait for a Promise and get its fulfillment value. It can only be used inside an async function or at the top level of a module.

Depending on your environment and the targeted platform, you can try to add "type": "module" in your package.json.

If that doesn't work, note that it is not required to load the initial state with the constructor and you can set it with the resolve of the AsyncStorage.getItem Promise, something like:

import AsyncStorage from '@react-native-async-storage/async-storage';
import PocketBase, { AsyncAuthStore } from 'pocketbase';

const store = new AsyncAuthStore({
    save: async (serialized) => AsyncStorage.setItem('pb_auth', serialized),
});

AsyncStorage.getItem('pb_auth').then((value) => {
    // if exist `value` should be a serialized json
    try {
        const parsed = JSON.parse(value) || {};

        store.save(parsed.token || "", parsed.model || null);
    } catch (_) {}
})

const pb = new PocketBase('http://127.0.0.1:8090', store)

If neither of the suggested 2 options work, feel free to provide more details about your environment (eg. what Node.js and React Native versions you use, what platform you target, do you use expo, etc.) and I'll try to have a more detailed look at it.

mez commented 1 year ago

Thank you for the response @ganigeorgiev. The promise resolve route worked.

My env:

Confirmed it works for

ganigeorgiev commented 1 year ago

I'll consider with the next release to add support for both string and Promise initial values to ensure that the above Promise runs through the internal enqueue method and to minimize the boilerplate in case the environment doesn't support top-level awaits, aka. you'll be able to do just:

const store = new AsyncAuthStore({
    save:    async (serialized) => AsyncStorage.setItem('pb_auth', serialized),
    initial: AsyncStorage.getItem('pb_auth'),
});