Skip to content

Commit c621f5b

Browse files
committed
Unified emulator settings for Firestore
1 parent 5e5111b commit c621f5b

File tree

4 files changed

+139
-4
lines changed

4 files changed

+139
-4
lines changed

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/AccessHelper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public static FirebaseFirestore newFirebaseFirestore(
4141
asyncQueue,
4242
firebaseApp,
4343
instanceRegistry,
44+
null,
4445
null);
4546
}
4647

firebase-firestore/src/main/java/com/google/firebase/firestore/FirebaseFirestore.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import com.google.android.gms.tasks.Tasks;
2828
import com.google.firebase.FirebaseApp;
2929
import com.google.firebase.auth.internal.InternalAuthProvider;
30+
import com.google.firebase.emulators.EmulatedServiceSettings;
31+
import com.google.firebase.emulators.EmulatorSettings;
32+
import com.google.firebase.emulators.FirebaseEmulator;
3033
import com.google.firebase.firestore.FirebaseFirestoreException.Code;
3134
import com.google.firebase.firestore.auth.CredentialsProvider;
3235
import com.google.firebase.firestore.auth.EmptyCredentialsProvider;
@@ -55,6 +58,9 @@
5558
*/
5659
public class FirebaseFirestore {
5760

61+
/** Emulator identifier. See {@link FirebaseApp#enableEmulators(EmulatorSettings)} */
62+
public static FirebaseEmulator EMULATOR = FirebaseEmulator.forName("firestore");
63+
5864
/**
5965
* Provides a registry management interface for {@code FirebaseFirestore} instances.
6066
*
@@ -81,6 +87,7 @@ public interface InstanceRegistry {
8187
private FirebaseFirestoreSettings settings;
8288
private volatile FirestoreClient client;
8389
private final GrpcMetadataProvider metadataProvider;
90+
private final EmulatedServiceSettings emulatorSettings;
8491

8592
@NonNull
8693
public static FirebaseFirestore getInstance() {
@@ -144,7 +151,8 @@ static FirebaseFirestore newInstance(
144151
queue,
145152
app,
146153
instanceRegistry,
147-
metadataProvider);
154+
metadataProvider,
155+
app.getEmulatorSettings().getServiceSettings(EMULATOR));
148156
return firestore;
149157
}
150158

@@ -157,7 +165,8 @@ static FirebaseFirestore newInstance(
157165
AsyncQueue asyncQueue,
158166
@Nullable FirebaseApp firebaseApp,
159167
InstanceRegistry instanceRegistry,
160-
@Nullable GrpcMetadataProvider metadataProvider) {
168+
@Nullable GrpcMetadataProvider metadataProvider,
169+
@Nullable EmulatedServiceSettings emulatorSettings) {
161170
this.context = checkNotNull(context);
162171
this.databaseId = checkNotNull(checkNotNull(databaseId));
163172
this.userDataReader = new UserDataReader(databaseId);
@@ -168,8 +177,12 @@ static FirebaseFirestore newInstance(
168177
this.firebaseApp = firebaseApp;
169178
this.instanceRegistry = instanceRegistry;
170179
this.metadataProvider = metadataProvider;
180+
this.emulatorSettings = emulatorSettings;
171181

172-
settings = new FirebaseFirestoreSettings.Builder().build();
182+
this.settings = new FirebaseFirestoreSettings.Builder().build();
183+
if (this.emulatorSettings != null) {
184+
this.settings = mergeEmulatorSettings(settings, emulatorSettings);
185+
}
173186
}
174187

175188
/** Returns the settings used by this {@code FirebaseFirestore} object. */
@@ -193,6 +206,11 @@ public void setFirestoreSettings(@NonNull FirebaseFirestoreSettings settings) {
193206
+ "You can only call setFirestoreSettings() before calling any other methods on a "
194207
+ "FirebaseFirestore object.");
195208
}
209+
210+
if (this.emulatorSettings != null) {
211+
settings = mergeEmulatorSettings(settings, this.emulatorSettings);
212+
}
213+
196214
this.settings = settings;
197215
}
198216
}
@@ -215,6 +233,23 @@ private void ensureClientConfigured() {
215233
}
216234
}
217235

236+
private FirebaseFirestoreSettings mergeEmulatorSettings(
237+
@NonNull FirebaseFirestoreSettings settings,
238+
@NonNull EmulatedServiceSettings emulatorSettings) {
239+
240+
if (!FirebaseFirestoreSettings.DEFAULT_HOST.equals(settings.getHost())) {
241+
throw new IllegalStateException(
242+
"Cannot change the Firestore host through FirebaseFirestoreSettings when "
243+
+ "EmulatedServiceSettings are also in effect. "
244+
+ "Make sure to only set the host in one location.");
245+
}
246+
247+
return new FirebaseFirestoreSettings.Builder(settings)
248+
.setHost(emulatorSettings.getHost() + ":" + emulatorSettings.getPort())
249+
.setSslEnabled(false)
250+
.build();
251+
}
252+
218253
/** Returns the FirebaseApp instance to which this {@code FirebaseFirestore} belongs. */
219254
@NonNull
220255
public FirebaseApp getApp() {

firebase-firestore/src/main/java/com/google/firebase/firestore/FirebaseFirestoreSettings.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ public final class FirebaseFirestoreSettings {
2727
*/
2828
public static final long CACHE_SIZE_UNLIMITED = -1;
2929

30+
/** @hide */
31+
public static final String DEFAULT_HOST = "firestore.googleapis.com";
32+
3033
private static final long MINIMUM_CACHE_BYTES = 1 * 1024 * 1024; // 1 MB
3134
private static final long DEFAULT_CACHE_SIZE_BYTES = 100 * 1024 * 1024; // 100 MB
32-
private static final String DEFAULT_HOST = "firestore.googleapis.com";
3335
private static final boolean DEFAULT_TIMESTAMPS_IN_SNAPSHOTS_ENABLED = true;
3436

3537
/** A Builder for creating {@code FirebaseFirestoreSettings}. */
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import static org.junit.Assert.assertEquals;
18+
import static org.junit.Assert.assertFalse;
19+
20+
import androidx.annotation.NonNull;
21+
import androidx.test.platform.app.InstrumentationRegistry;
22+
import com.google.firebase.FirebaseApp;
23+
import com.google.firebase.FirebaseOptions;
24+
import com.google.firebase.emulators.EmulatedServiceSettings;
25+
import com.google.firebase.emulators.EmulatorSettings;
26+
import org.junit.Test;
27+
import org.junit.runner.RunWith;
28+
import org.robolectric.RobolectricTestRunner;
29+
import org.robolectric.annotation.Config;
30+
31+
@RunWith(RobolectricTestRunner.class)
32+
@Config(manifest = Config.NONE)
33+
public class FirebaseFirestoreTest {
34+
35+
@Test
36+
public void getInstance_withEmulator() {
37+
FirebaseApp app = getApp("getInstance_withEmulator");
38+
39+
app.enableEmulators(
40+
new EmulatorSettings.Builder()
41+
.addEmulatedService(
42+
FirebaseFirestore.EMULATOR, new EmulatedServiceSettings("10.0.2.2", 8080))
43+
.build());
44+
45+
FirebaseFirestore firestore = FirebaseFirestore.getInstance(app);
46+
FirebaseFirestoreSettings settings = firestore.getFirestoreSettings();
47+
48+
assertEquals(settings.getHost(), "10.0.2.2:8080");
49+
assertFalse(settings.isSslEnabled());
50+
}
51+
52+
@Test
53+
public void getInstance_withEmulator_mergeSettingsSuccess() {
54+
FirebaseApp app = getApp("getInstance_withEmulator_mergeSettingsSuccess");
55+
app.enableEmulators(
56+
new EmulatorSettings.Builder()
57+
.addEmulatedService(
58+
FirebaseFirestore.EMULATOR, new EmulatedServiceSettings("10.0.2.2", 8080))
59+
.build());
60+
61+
FirebaseFirestore firestore = FirebaseFirestore.getInstance(app);
62+
firestore.setFirestoreSettings(
63+
new FirebaseFirestoreSettings.Builder().setPersistenceEnabled(false).build());
64+
65+
FirebaseFirestoreSettings settings = firestore.getFirestoreSettings();
66+
67+
assertEquals(settings.getHost(), "10.0.2.2:8080");
68+
assertFalse(settings.isSslEnabled());
69+
assertFalse(settings.isPersistenceEnabled());
70+
}
71+
72+
@Test(expected = IllegalStateException.class)
73+
public void getInstance_withEmulator_mergeSettingsFailure() {
74+
FirebaseApp app = getApp("getInstance_withEmulator_mergeSettingsFailure");
75+
app.enableEmulators(
76+
new EmulatorSettings.Builder()
77+
.addEmulatedService(
78+
FirebaseFirestore.EMULATOR, new EmulatedServiceSettings("10.0.2.2", 8080))
79+
.build());
80+
81+
FirebaseFirestore firestore = FirebaseFirestore.getInstance(app);
82+
firestore.setFirestoreSettings(
83+
new FirebaseFirestoreSettings.Builder().setHost("myhost.com").build());
84+
}
85+
86+
@NonNull
87+
private FirebaseApp getApp(@NonNull String name) {
88+
return FirebaseApp.initializeApp(
89+
InstrumentationRegistry.getInstrumentation().getContext(),
90+
new FirebaseOptions.Builder()
91+
.setApplicationId("appid")
92+
.setApiKey("apikey")
93+
.setProjectId("projectid")
94+
.build(),
95+
name);
96+
}
97+
}

0 commit comments

Comments
 (0)