Skip to content

Commit 47f33ec

Browse files
committed
Merge branch 'master' of github.com:firebase/firebase-android-sdk into fis_sdk
2 parents 16521a1 + af38de9 commit 47f33ec

File tree

35 files changed

+1677
-212
lines changed

35 files changed

+1677
-212
lines changed

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/FirebaseLibraryExtension.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import com.google.common.collect.ImmutableSet;
1818
import com.google.firebase.gradle.plugins.ci.device.FirebaseTestLabExtension;
19+
import java.util.Collections;
1920
import java.util.HashSet;
2021
import java.util.Set;
2122
import java.util.stream.Collectors;
@@ -39,7 +40,7 @@ public class FirebaseLibraryExtension {
3940
public boolean publishSources;
4041

4142
/** Static analysis configuration. */
42-
public final FirebaseStaticAnalysis staticAnalysis = new FirebaseStaticAnalysis();
43+
public final FirebaseStaticAnalysis staticAnalysis;
4344

4445
/** Firebase Test Lab configuration/ */
4546
public final FirebaseTestLabExtension testLab;
@@ -78,6 +79,20 @@ public FirebaseLibraryExtension(Project project) {
7879
artifactId.set(new DefaultProvider<>(project::getName));
7980
groupId.set(new DefaultProvider<>(() -> project.getGroup().toString()));
8081
}
82+
this.staticAnalysis = initializeStaticAnalysis(project);
83+
}
84+
85+
private FirebaseStaticAnalysis initializeStaticAnalysis(Project project) {
86+
return new FirebaseStaticAnalysis(
87+
projectsFromProperty(project, "firebase.checks.errorproneProjects"),
88+
projectsFromProperty(project, "firebase.checks.lintProjects"));
89+
}
90+
91+
private Set<String> projectsFromProperty(Project project, String propertyName) {
92+
if (!project.hasProperty(propertyName)) {
93+
return Collections.emptySet();
94+
}
95+
return ImmutableSet.copyOf(project.property(propertyName).toString().split(",", -1));
8196
}
8297

8398
/** Configure Firebase Test Lab. */

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/FirebaseLibraryPlugin.java

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,13 @@
1717
import com.android.build.gradle.LibraryExtension;
1818
import com.google.common.collect.ImmutableList;
1919
import com.google.common.collect.ImmutableMap;
20-
import com.google.common.collect.ImmutableSet;
2120
import com.google.firebase.gradle.plugins.ci.device.FirebaseTestServer;
2221
import org.gradle.api.Plugin;
2322
import org.gradle.api.Project;
2423
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile;
2524

26-
import java.util.Set;
27-
2825
public class FirebaseLibraryPlugin implements Plugin<Project> {
2926

30-
private static final Set<String> KOTLIN_CHECKS =
31-
ImmutableSet.of(
32-
"FirebaseNoHardKeywords",
33-
"FirebaseLambdaLast",
34-
"FirebaseUnknownNullness",
35-
"FirebaseKotlinPropertyAccess");
36-
3727
@Override
3828
public void apply(Project project) {
3929
project.apply(ImmutableMap.of("plugin", "com.android.library"));
@@ -106,11 +96,6 @@ private static void setupStaticAnalysis(
10696
}
10797
}));
10898

109-
library.staticAnalysis.subscribeToKotlinInteropLintDisabled(
110-
() ->
111-
android.lintOptions(
112-
lintOptions -> lintOptions.disable(KOTLIN_CHECKS.toArray(new String[0]))));
113-
11499
project.getTasks().register("firebaseLint", task -> task.dependsOn("lint"));
115100
}
116101

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/FirebaseStaticAnalysis.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,45 +14,15 @@
1414

1515
package com.google.firebase.gradle.plugins;
1616

17-
import com.google.common.collect.ImmutableSet;
18-
19-
import java.util.HashSet;
2017
import java.util.Set;
21-
import java.util.function.Consumer;
2218

2319
public class FirebaseStaticAnalysis {
2420
public Set<String> errorproneCheckProjects;
2521
public Set<String> androidLintCheckProjects;
2622

27-
28-
private boolean disableKotlinInteropLint;
29-
30-
private final Set<Runnable> kotlinInteropLintDisabledSubscribers = new HashSet<>();
31-
32-
public FirebaseStaticAnalysis() {
33-
this(ImmutableSet.of(":tools:errorprone"), ImmutableSet.of(":tools:lint"));
34-
}
35-
36-
public FirebaseStaticAnalysis(Set<String> errorproneCheckProjects, Set<String> androidLintCheckProjects) {
23+
public FirebaseStaticAnalysis(
24+
Set<String> errorproneCheckProjects, Set<String> androidLintCheckProjects) {
3725
this.errorproneCheckProjects = errorproneCheckProjects;
3826
this.androidLintCheckProjects = androidLintCheckProjects;
3927
}
40-
41-
/** Indicates whether Kotlin Interop Lint checks are enabled for public APIs of the library. */
42-
public void disableKotlinInteropLint() {
43-
if (disableKotlinInteropLint) {
44-
return;
45-
}
46-
disableKotlinInteropLint = true;
47-
for (Runnable subscription : kotlinInteropLintDisabledSubscribers) {
48-
subscription.run();
49-
}
50-
}
51-
52-
void subscribeToKotlinInteropLintDisabled(Runnable subscription) {
53-
this.kotlinInteropLintDisabledSubscribers.add(subscription);
54-
if (disableKotlinInteropLint) {
55-
subscription.run();
56-
}
57-
}
5828
}

buildSrc/src/test/groovy/com/google/firebase/gradle/plugins/publish/PublishingPluginSpec.groovy

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ class PublishingPluginSpec extends Specification {
2929
plugins {
3030
id 'firebase-library'
3131
}
32-
firebaseLibrary {
33-
staticAnalysis {
34-
errorproneCheckProjects = []
35-
androidLintCheckProjects = []
36-
}
37-
}
3832
group = '${group}'
3933
version = '${version}'
4034
<% if (latestReleasedVersion) println "ext.latestReleasedVersion = $latestReleasedVersion" %>

firebase-common/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<manifest
33
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
45
package="com.google.firebase">
56
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
67
<!--<uses-sdk android:minSdkVersion="14"/>-->
78
<application>
89

10+
<service android:name="com.google.firebase.components.ComponentDiscoveryService"
11+
android:directBootAware="true" android:exported="false"
12+
tools:targetApi="n" />
13+
914
<provider
1015
android:name="com.google.firebase.provider.FirebaseInitProvider"
1116
android:authorities="${applicationId}.firebaseinitprovider"

firebase-database/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
# 19.1.0
2+
- [feature] Added support for the Firebase Database Emulator. To connect to
3+
the emulator, specify "http://<emulatorHost>/?ns=<projectId>" as your
4+
Database URL (via `FirebaseDatabase.getInstance(String)`).
5+
Note that if you are running the Database Emulator on "localhost" and
6+
connecting from an app that is running inside an Android Emulator, the
7+
emulator host will be "10.0.2.2" followed by its port.
8+
19
# 18.0.1
210
- [changed] The SDK now reports the correct version number (via
311
`FirebaseDatabase.getSdkVersion()`).

firebase-database/src/androidTest/java/com/google/firebase/database/DataTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,9 +1081,9 @@ public void urlEncodingAndDecodingWorks()
10811081
new DatabaseReference(
10821082
IntegrationTestValues.getNamespace() + "/a%b&c@d/space: /non-ascii:ø", ctx);
10831083
String result = ref.toString();
1084-
String expected =
1084+
String encoded =
10851085
IntegrationTestValues.getNamespace() + "/a%25b%26c%40d/space%3A%20/non-ascii%3A%C3%B8";
1086-
assertEquals(expected, result);
1086+
assertEquals(encoded, result);
10871087

10881088
String child = "" + new Random().nextInt(100000000);
10891089
new WriteFuture(ref.child(child), "testdata").timedGet();

firebase-database/src/androidTest/java/com/google/firebase/database/FirebaseDatabaseTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public void persistenceSettings() {
170170
config.setPersistenceCacheSizeBytes(1 * 1024 * 1024);
171171

172172
try {
173-
FirebaseDatabase db = new DatabaseReference("", config).getDatabase();
173+
FirebaseDatabase db = new DatabaseReference("http://localhost", config).getDatabase();
174174
db.setPersistenceCacheSizeBytes(1 * 1024 * 1024);
175175
fail("should throw - can't modify after init");
176176
} catch (DatabaseException e) {

firebase-database/src/androidTest/java/com/google/firebase/database/RealtimeTest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import androidx.test.runner.AndroidJUnit4;
2424
import com.google.firebase.database.core.DatabaseConfig;
2525
import com.google.firebase.database.core.RepoManager;
26-
import com.google.firebase.database.core.utilities.ParsedUrl;
27-
import com.google.firebase.database.core.utilities.Utilities;
2826
import com.google.firebase.database.future.ReadFuture;
2927
import com.google.firebase.database.future.WriteFuture;
3028
import java.util.List;
@@ -48,21 +46,6 @@ public void tearDown() {
4846
IntegrationTestHelpers.failOnFirstUncaughtException();
4947
}
5048

51-
@Test
52-
public void testUrlParsing() throws DatabaseException {
53-
ParsedUrl parsed = Utilities.parseUrl("http://gsoltis.fblocal.com:9000");
54-
assertEquals(parsed.path.toString(), "/");
55-
assertEquals(parsed.repoInfo.host, "gsoltis.fblocal.com:9000");
56-
assertEquals(parsed.repoInfo.internalHost, "gsoltis.fblocal.com:9000");
57-
assertEquals(parsed.repoInfo.secure, false);
58-
59-
parsed = Utilities.parseUrl("http://gsoltis.firebaseio.com/foo/bar");
60-
assertEquals(parsed.path.toString(), "/foo/bar");
61-
assertEquals(parsed.repoInfo.host, "gsoltis.firebaseio.com");
62-
assertEquals(parsed.repoInfo.internalHost, "gsoltis.firebaseio.com");
63-
assertEquals(parsed.repoInfo.secure, true);
64-
}
65-
6649
@Test
6750
public void testOnDisconnectSetWorks()
6851
throws DatabaseException, TestFailure, TimeoutException, InterruptedException {

firebase-database/src/main/java/com/google/firebase/database/core/utilities/DefaultRunLoop.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,20 @@ public static String messageForException(Throwable t) {
128128
+ "https://firebase.google.com/docs/database/ios/structure-data#best_practices_for_data_structure"
129129
+ " and "
130130
+ "https://firebase.google.com/docs/database/android/retrieve-data#filtering_data";
131+
} else if (t instanceof NoClassDefFoundError) {
132+
return "A symbol that the Firebase Database SDK depends on failed to load. This usually "
133+
+ "indicates that your project includes an incompatible version of another Firebase "
134+
+ "dependency. If updating your dependencies to the latest version does not resolve "
135+
+ "this issue, please file a report at https://github.com/firebase/firebase-android-sdk";
131136
} else if (t instanceof DatabaseException) {
132137
// Exception should be self-explanatory and they shouldn't contact support.
133138
return "";
134139
} else {
135140
return "Uncaught exception in Firebase Database runloop ("
136141
+ FirebaseDatabase.getSdkVersion()
137-
+ "). Please report to [email protected]";
142+
+ "). If you are not already on the latest version of the Firebase SDKs, try updating "
143+
+ "your dependencies. Should this problem persist, please file a report at "
144+
+ "https://github.com/firebase/firebase-android-sdk";
138145
}
139146
}
140147
}

firebase-database/src/main/java/com/google/firebase/database/core/utilities/ParsedUrl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,15 @@ public class ParsedUrl {
2121

2222
public RepoInfo repoInfo;
2323
public Path path;
24+
25+
@Override
26+
public boolean equals(Object o) {
27+
if (this == o) return true;
28+
if (o == null || getClass() != o.getClass()) return false;
29+
30+
ParsedUrl parsedUrl = (ParsedUrl) o;
31+
32+
if (!repoInfo.equals(parsedUrl.repoInfo)) return false;
33+
return path.equals(parsedUrl.path);
34+
}
2435
}

firebase-database/src/main/java/com/google/firebase/database/core/utilities/Utilities.java

Lines changed: 51 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.firebase.database.core.utilities;
1616

17+
import android.net.Uri;
1718
import android.util.Base64;
1819
import com.google.android.gms.tasks.Task;
1920
import com.google.android.gms.tasks.TaskCompletionSource;
@@ -23,83 +24,85 @@
2324
import com.google.firebase.database.core.Path;
2425
import com.google.firebase.database.core.RepoInfo;
2526
import java.io.UnsupportedEncodingException;
26-
import java.net.URI;
27-
import java.net.URISyntaxException;
28-
import java.net.URLEncoder;
2927
import java.security.MessageDigest;
3028
import java.security.NoSuchAlgorithmException;
31-
import java.util.ArrayList;
3229
import java.util.Map;
3330

3431
public class Utilities {
3532
private static final char[] HEX_CHARACTERS = "0123456789abcdef".toCharArray();
3633

3734
public static ParsedUrl parseUrl(String url) throws DatabaseException {
38-
String original = url;
3935
try {
40-
int schemeOffset = original.indexOf("//");
41-
if (schemeOffset == -1) {
42-
throw new URISyntaxException(original, "Invalid scheme specified");
43-
}
44-
int pathOffset = original.substring(schemeOffset + 2).indexOf("/");
45-
if (pathOffset != -1) {
46-
pathOffset += schemeOffset + 2;
47-
String[] pathSegments = original.substring(pathOffset).split("/", -1);
48-
StringBuilder builder = new StringBuilder();
49-
for (int i = 0; i < pathSegments.length; ++i) {
50-
if (!pathSegments[i].equals("")) {
51-
builder.append("/");
52-
builder.append(URLEncoder.encode(pathSegments[i], "UTF-8"));
53-
}
54-
}
55-
original = original.substring(0, pathOffset) + builder.toString();
56-
}
36+
Uri uri = Uri.parse(url);
5737

58-
URI uri = new URI(original);
59-
// URLEncoding a space turns it into a '+', which is different
60-
// from our expected behavior. Do a manual replace to fix it.
61-
String pathString = uri.getPath().replace("+", " ");
62-
Validation.validateRootPathString(pathString);
63-
Path path = new Path(pathString);
6438
String scheme = uri.getScheme();
39+
if (scheme == null) {
40+
throw new IllegalArgumentException("Database URL does not specify a URL scheme");
41+
}
42+
43+
String host = uri.getHost();
44+
if (host == null) {
45+
throw new IllegalArgumentException("Database URL does not specify a valid host");
46+
}
6547

6648
RepoInfo repoInfo = new RepoInfo();
67-
repoInfo.host = uri.getHost().toLowerCase();
49+
repoInfo.host = host.toLowerCase();
6850

6951
int port = uri.getPort();
7052
if (port != -1) {
71-
repoInfo.secure = scheme.equals("https");
53+
repoInfo.secure = scheme.equals("https") || scheme.equals("wss");
7254
repoInfo.host += ":" + port;
7355
} else {
7456
repoInfo.secure = true;
7557
}
76-
String[] parts = repoInfo.host.split("\\.", -1);
7758

78-
repoInfo.namespace = parts[0].toLowerCase();
59+
String namespaceParam = uri.getQueryParameter("ns");
60+
if (namespaceParam != null) {
61+
repoInfo.namespace = namespaceParam;
62+
} else {
63+
String[] parts = host.split("\\.", -1);
64+
repoInfo.namespace = parts[0].toLowerCase();
65+
}
66+
7967
repoInfo.internalHost = repoInfo.host;
68+
69+
String originalPathString = extractPathString(url);
70+
// URLEncoding a space turns it into a '+', which is different
71+
// from our expected behavior. Do a manual replace to fix it.
72+
originalPathString = originalPathString.replace("+", " ");
73+
Validation.validateRootPathString(originalPathString);
74+
8075
ParsedUrl parsedUrl = new ParsedUrl();
81-
parsedUrl.path = path;
76+
parsedUrl.path = new Path(originalPathString);
8277
parsedUrl.repoInfo = repoInfo;
83-
return parsedUrl;
8478

85-
} catch (URISyntaxException e) {
86-
throw new DatabaseException("Invalid Firebase Database url specified", e);
87-
} catch (UnsupportedEncodingException e) {
88-
throw new DatabaseException("Failed to URLEncode the path", e);
79+
return parsedUrl;
80+
} catch (Exception e) {
81+
throw new DatabaseException("Invalid Firebase Database url specified: " + url, e);
8982
}
9083
}
9184

92-
public static String[] splitIntoFrames(String src, int maxFrameSize) {
93-
if (src.length() <= maxFrameSize) {
94-
return new String[] {src};
95-
} else {
96-
ArrayList<String> segs = new ArrayList<String>();
97-
for (int i = 0; i < src.length(); i += maxFrameSize) {
98-
int end = Math.min(i + maxFrameSize, src.length());
99-
String seg = src.substring(i, end);
100-
segs.add(seg);
85+
/**
86+
* Extracts the path string from the original URL without changing the encoding (unlike
87+
* Uri.getPath()).
88+
*/
89+
private static String extractPathString(String originalUrl) {
90+
int schemeOffset = originalUrl.indexOf("//");
91+
if (schemeOffset == -1) {
92+
throw new DatabaseException("Firebase Database URL is missing URL scheme");
93+
}
94+
95+
String urlWithoutScheme = originalUrl.substring(schemeOffset + 2);
96+
int pathOffset = urlWithoutScheme.indexOf("/");
97+
if (pathOffset != -1) {
98+
int queryOffset = urlWithoutScheme.indexOf("?");
99+
if (queryOffset != -1) {
100+
return urlWithoutScheme.substring(pathOffset + 1, queryOffset);
101+
} else {
102+
return urlWithoutScheme.substring(pathOffset + 1);
101103
}
102-
return segs.toArray(new String[segs.size()]);
104+
} else {
105+
return "";
103106
}
104107
}
105108

0 commit comments

Comments
 (0)