-
Notifications
You must be signed in to change notification settings - Fork 586
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
Realm with sync enabled CRASHES the whole app when "path" is specified #4659
Comments
Thanks for the report @rogerkerse, and for the reproduction repo. I can confirm I see the same issue here. I'll do some investigation into the root cause and let you know more when I do. |
Hey @rogerkerse, I've had a closer look at your example and the issue here is that you are initially opening Do you actually want to open the same Realm file as non-synced and synced? If so, I believe you need to use writeCopyTo to convert the local Realm to a synced Realm. It might be that there's a better way to handle what you want to do though, please feel free to describe your use case in more detail and I can try to help. |
Well our situation is that app is usable logged in or logged out. Once user decides to log in, then we want to sync all data that he already produced or new data that he is going to produce. Keeping 2 separate realms for that purpose makes it extremely complicated to handle. Explaining the scenario that I mean:
|
Yes, RealmSync does not conform to modern UX/onboarding standards where a user may want to experience the app before logging in. Thats why we use Local Realm and built our own syncing logic from scratch. We would prefer to switch to Realm's solution, but it simply is too complicated currently. We use a local realm that awaits user login. Then we even give the user the option if they want to have their data synced to the cloud. If they consent, we sync the current state of the db and start version tracking from there. I'm sure Realm Sync can achieve the same thing easily by considering all data entered into a synced realm as offline data until credentials are provided (same behavior as if the device is in airplane mode). |
@ZComwiz We hare very recently made an option to convert the local realm to a synced realm for this particular use case (writeCopyTo) as @tomduncalf described. I assume that option wasn't available when you ran into the issue? It's definitely a use case we want to support, so feedback on how that solution works is appreciated. |
@rogerkerse, it sounds like you would need to use I am double checking with my colleague who implemented the feature, but I think the way to use it would be to open one Realm as a local Realm, then when the user logs in, write a copy of this Realm to a new, synced Realm. I've created an example using our Node.js API here: https://github.com/tomduncalf/realm_4659_path_crashes_sync_node/blob/main/app.js, you can see that initially we open a local Realm, Please let me know if anything is unclear or if you need more assistance with this! |
@rogerkerse Did you have a chance to try the suggestion outline above? |
Trying to implement it in real world scenario but getting |
@rogerkerse Would it be helpful if we provided an example of doing the same using Realm React? I didn't realise you were using React Native when I provided my example |
@tomduncalf yes that would be extremely helpful to see in react-native (on the fly switching out RealmContext, useQuery etc.), thank you |
@rogerkerse, good luck. In the real world this task is riddled with race conditions. I look forward to seeing what the realm team proposes, but this should just be a boolean on realm directly that should handle offline and online storage. Its much easier to do on the C level / managing the web-socket connection as a parameter than for us to manually throw data around on the front end, but I don't know how Realm implemented Sync. |
@rogerkerse I'm still looking into this, you're right that it's non trivial with Realm React so I am trying to work out the best way to do this, and talking to the team about if we need to add additional functionality to support this flow. Sorry for the trouble! @ZComwiz I'll chat to the team about your suggestion as I do agree this is somewhat complicated but there might be valid reasons for it being so. I'll get back to you with our thoughts, it might be an area where we can improve our API in future for sure. |
Hey @tomduncalf is there any update on the issue? 😊 |
@kneth @tomduncalf @bmunkholm, this is a major issue for our team. We have been working extensively on a work around, but it makes far more sense to work together to help you make a proper API. Is there anything we can do to help move this along? |
@ZComwiz @rogerkerse Just want to chime in here. Instead of migrating a local realm to sync when a user logs in, why not start with an anonymous user in a synced realm, and then link the user to an authorized one (email, oauth, etc) when they sign up? We have documentation on this. Also we are planning on making the migration from non-sync to synced a bit more intuitive. |
@takameyer thanks for your reply! Is it possible in that model to not sync certain collections until a user toggles a setting (keeping some objects purely local)? |
@ZComwiz We don't support exactly what you are describing. If that’s something you need, please create a feature request and we can get it on our radar. It is possible to pause sync, but this can't be done on a per model basis: |
In the pause() case, can you pause indefinitely until a user toggles a switch? Will records appear locally in their device? We don't need a collection by collection condition per say. We need to disable sync until a user explicitly enables it but we need them to have their local realm be populated in all cases for functionality purposes. |
@ZComwiz That should theoretically work. Realm is offline first, so if sync is disabled, you would just be writing to a local realm. I can foresee a possible issue, that on app restart, it will attempt to sync that local data when the realm is opened. Is there a reason you don't want the anonymous data in the cloud? You could create a cleanup trigger that purges anonymous user data after a period of time. |
@takameyer minimize data collection where possible if the user does not require it. |
We investigated this as a team today and found the app needs a change to convert from a local to a synced Realm. Most notably:
We acknowledge that the process for upgrading a local to a synced Realm is a bit involved and we're tracking this issue to improve the experience: #4334. Please see our suggestions applied below. import React, {useMemo, useEffect, useCallback, useState, useRef} from 'react';
import {View, Text, StyleSheet} from 'react-native';
import {AppProvider, createRealmContext, useApp} from '@realm/react';
import {Configuration, Credentials, SyncConfiguration} from 'realm';
const RealmContext = createRealmContext({
schema: [],
// This line crashes the app with sync.
path: 'local.realm',
});
const {RealmProvider} = RealmContext;
const MONGO_ATLAS_APP_ID = '---'; // Change to your mongo atlas app id
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'lightblue',
},
});
const AppComponent = () => {
const realmApp = useApp();
const [user, setUser] = useState<Realm.User<any>>();
const realm = useRef<Realm>(null);
const config: Configuration | undefined = useMemo(
() =>
user
? {path: 'sync.realm', sync: {flexible: true, user: user}}
: undefined,
[user],
);
const loginToRealm = useCallback(async () => {
// Waiting 2 seconds until login as a test simulating logging in later in the app's user flow
await new Promise(resolve => setTimeout(resolve, 2000));
const credentials = Credentials.anonymous();
try {
const realmUser = await realmApp.logIn(credentials);
console.log('Successfully logged in!', realmUser.id);
setUser(realmUser);
} catch (error) {
console.error('Failed to log in', (error as any).message);
}
}, [realmApp]);
useEffect(() => {
loginToRealm();
}, [loginToRealm]);
if (config && !Realm.exists(config) && realm.current) {
console.log(`Converting ${realm.current.path} to a synced Realm`);
// We need to convert the local realm into a synced Realm before opening it
realm.current.writeCopyTo(config);
}
return (
<RealmProvider {...config} realmRef={realm}>
<View style={styles.container}>
<Text>User {user?.id ?? 'not logged in'}</Text>
</View>
</RealmProvider>
);
};
const App = () => {
return (
<AppProvider id={MONGO_ATLAS_APP_ID}>
<AppComponent />
</AppProvider>
);
};
export default App; |
@kraenhansen I’ve been trying to implement your solution, but unfortunately running into problems with setting up a subscription. This is the error that I'm getting after logging in:
It seems that the subscription doesn't exist at the time and so the write gets reverted. Can you help us by pointing out a way to get past this? Also, what about the data from local realm, that we want to carry over to the synced realm, but don't want to sync with the server? Our app has the option to turn off cloud syncing. Thus, user can limit what data gets synced, but we still want to store some information about their account. Is there any way to implement this? My code demo: https://github.com/soliloquyx/realm-sync-demo-1 |
@soliloquyx We have recently discovered that converting a local Realm to a flexible sync Realm is not yet supported: realm/realm-core#5798 It means that you will have to copy objects from your local Realm to your flexible sync Realm. |
@kneth, has the realm team tried talking to some of their MDB customers to understand their use cases? The current implementation of Atlas Sync Realm seems pretty out of touch with the needs of modern day mobile apps. For instance, if an app developer wants to implement a task app, good UX may let them use the app and start adding objects to realm, but only sign in to save their data to the cloud or share it with colleagues. That would delay user login to an unknown time in the app life cycle and while it may be necessary for Mongo Atlas to set the owner of those documents, Realm should be able to persist data locally until being logged in which will give app developers a lot more flexibility to create proper UX flows that do not force a user to sign in before they understand more about the app they are using and if they feel comfortable letting that app handle their data on the cloud. I'd love to chat with your team more and give some references to design patterns that should be supported that we use in industry developed at UC Berkeley and Stanford. |
@ZComwiz Product for Realm here. Yes - we speak to users and customers all the time. I'm always happy to have a call and discuss your app, company, and use cases you'd like to support. You can email me at [email protected] and we can setup a time to talk. |
How frequently does the bug occur?
All the time
Description
I created a demo project that crashes after login immediatelly when in realm configuration we add
path
variable. It seems like unintended behaviour. When removingpath
no crash appears.https://github.com/boltss/realm-sync-demo demo project. That crashes when
path
is specified.In our case having 2 realms side by side is mandatory. And to separate them we need to specify
path
to one.Stacktrace & log output
Can you reproduce the bug?
Yes, always
Reproduction Steps
open
App.tsx
and either removing or addingpath
makes it run or crash.Crash happens after
realm.logIn()
Version
10.19.1
What SDK flavour are you using?
Atlas App Services (auth, functions, etc.)
Are you using encryption?
No, not using encryption
Platform OS and version(s)
iOS 15.5
Build environment
System:
OS: macOS 12.4
CPU: (10) arm64 Apple M1 Pro
Memory: 105.23 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 17.9.0 - ~/.volta/tools/image/node/17.9.0/bin/node
Yarn: 1.22.18 - ~/.volta/tools/image/yarn/1.22.18/bin/yarn
npm: 8.5.5 - ~/.volta/tools/image/node/17.9.0/bin/npm
Watchman: 2022.03.21.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5
Android SDK:
Android NDK: 23.0.7344513-beta4
IDEs:
Android Studio: Chipmunk 2021.2.1 Patch 1 Chipmunk 2021.2.1 Patch 1
Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild
Languages:
Java: 18.0.1 - /Users/username/.jenv/shims/javac
npmPackages:
@react-native-community/cli: Not Found
react: 17.0.2 => 17.0.2
react-native: 0.68.2 => 0.68.2
react-native-macos: Not Found
npmGlobalPackages:
react-native: Not Found
Cocoapods version
1.11.3
The text was updated successfully, but these errors were encountered: