diff --git a/realm/realm-library/src/objectServer/java/io/realm/SyncManager.java b/realm/realm-library/src/objectServer/java/io/realm/SyncManager.java index 43381058c4..48659d5ba6 100644 --- a/realm/realm-library/src/objectServer/java/io/realm/SyncManager.java +++ b/realm/realm-library/src/objectServer/java/io/realm/SyncManager.java @@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.URI; import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.cert.CertificateException; @@ -209,7 +210,7 @@ public static void setDefaultSessionErrorHandler(@Nullable SyncSession.ErrorHand * @return the {@link SyncSession} for the specified Realm. * @throws IllegalArgumentException if syncConfiguration is {@code null}. */ - public static synchronized SyncSession getSession(SyncConfiguration syncConfiguration) { + public static synchronized SyncSession getSession(SyncConfiguration syncConfiguration, URI... resolvedRealmURL) { // This will not create a new native (Object Store) session, this will only associate a Realm's path // with a SyncSession. Object Store's SyncManager is responsible of the life cycle (including creation) // of the native session, the provided Java wrap, helps interact with the native session, when reporting error @@ -226,6 +227,15 @@ public static synchronized SyncSession getSession(SyncConfiguration syncConfigur sessions.put(syncConfiguration.getPath(), session); if (sessions.size() == 1) { RealmLog.debug("first session created add network listener"); + if(resolvedRealmURL.length > 0) { + session.setResolvedRealmURI(resolvedRealmURL[0]); + } + // Currently when the user login, the Object Store will try to revive it's inactive sessions + // (stored previously after a logout). this will cause the OS to call bindSession to obtain an + // access token, however since the Realm might not be open yet, the wrapObjectStoreSessionIfRequired + // will not be invoked to wrap the OS store session with the Java session, the Sync client to not resume + // syncing. + session.getAccessToken(authServer, null); NetworkStateReceiver.addListener(networkListener); } } diff --git a/realm/realm-library/src/objectServer/java/io/realm/SyncSession.java b/realm/realm-library/src/objectServer/java/io/realm/SyncSession.java index 30ff8c8ad2..f05656a86f 100644 --- a/realm/realm-library/src/objectServer/java/io/realm/SyncSession.java +++ b/realm/realm-library/src/objectServer/java/io/realm/SyncSession.java @@ -378,7 +378,7 @@ public void uploadAllLocalChanges() throws InterruptedException { } } - public void setResolvedRealmURI(URI resolvedRealmURI) { + void setResolvedRealmURI(URI resolvedRealmURI) { this.resolvedRealmURI = resolvedRealmURI; } diff --git a/realm/realm-library/src/objectServer/java/io/realm/internal/SyncObjectServerFacade.java b/realm/realm-library/src/objectServer/java/io/realm/internal/SyncObjectServerFacade.java index 2b8616e8d7..80bbeecdb0 100644 --- a/realm/realm-library/src/objectServer/java/io/realm/internal/SyncObjectServerFacade.java +++ b/realm/realm-library/src/objectServer/java/io/realm/internal/SyncObjectServerFacade.java @@ -106,8 +106,7 @@ public static Context getApplicationContext() { @Override public void wrapObjectStoreSessionIfRequired(OsRealmConfig config) { if (config.getRealmConfiguration() instanceof SyncConfiguration) { - SyncSession session = SyncManager.getSession((SyncConfiguration) config.getRealmConfiguration()); - session.setResolvedRealmURI(config.getResolvedRealmURI()); + SyncManager.getSession((SyncConfiguration) config.getRealmConfiguration(), config.getResolvedRealmURI()); } } diff --git a/realm/realm-library/src/syncIntegrationTest/java/io/realm/SyncedRealmTests.java b/realm/realm-library/src/syncIntegrationTest/java/io/realm/SyncedRealmTests.java index 7eaa41f60a..e028c44150 100644 --- a/realm/realm-library/src/syncIntegrationTest/java/io/realm/SyncedRealmTests.java +++ b/realm/realm-library/src/syncIntegrationTest/java/io/realm/SyncedRealmTests.java @@ -49,6 +49,36 @@ @RunWith(AndroidJUnit4.class) public class SyncedRealmTests extends StandardIntegrationTest { + + @Test + public void loginLogoutResumeSyncing() throws InterruptedException { + String username = UUID.randomUUID().toString(); + String password = "password"; + SyncUser user = SyncUser.login(SyncCredentials.usernamePassword(username, password, true), Constants.AUTH_URL); + + SyncConfiguration config = new SyncConfiguration.Builder(user, Constants.USER_REALM) + .schema(StringOnly.class) + .build(); + + Realm realm = Realm.getInstance(config); + realm.beginTransaction(); + realm.createObject(StringOnly.class).setChars("Foo"); + realm.commitTransaction(); + SyncManager.getSession(config).uploadAllLocalChanges(); + user.logout(); + realm.close(); + + user = SyncUser.login(SyncCredentials.usernamePassword(username, password, false), Constants.AUTH_URL); + SyncConfiguration config2 = new SyncConfiguration.Builder(user, Constants.USER_REALM) + .schema(StringOnly.class) + .build(); + + Realm realm2 = Realm.getInstance(config2); + SyncManager.getSession(config2).downloadAllServerChanges(); + realm2.refresh(); + assertEquals(1, realm2.where(StringOnly.class).count()); + } + @Test @UiThreadTest public void waitForInitialRemoteData_mainThreadThrows() {