Skip to content

Patch caching fid in memory on successful registration. #1764

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

Merged
merged 6 commits into from
Jul 9, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ public class FirebaseInstallations implements FirebaseInstallationsApi {

/* used for thread-level synchronization of generating and persisting fids */
private static final Object lockGenerateFid = new Object();

/* file used for process-level synchronization of generating and persisting fids */
private static final String LOCKFILE_NAME_GENERATE_FID = "generatefid.lock";
private static final String CHIME_FIREBASE_APP_NAME = "CHIME_ANDROID_SDK";
Expand Down Expand Up @@ -225,7 +224,15 @@ String getName() {
@Override
public Task<String> getId() {
preConditionChecks();
return Tasks.forResult(doGetId());
// Return cached fid if available.
String fid = getCacheFid();
if (fid != null) {
return Tasks.forResult(fid);
}

Task<String> task = addGetIdListener();
backgroundExecutor.execute(this::doGetId);
return task;
}

/**
Expand All @@ -241,7 +248,11 @@ public Task<String> getId() {
public Task<InstallationTokenResult> getToken(boolean forceRefresh) {
preConditionChecks();
Task<InstallationTokenResult> task = addGetAuthTokenListener();
backgroundExecutor.execute(() -> doGetAuthToken(forceRefresh));
if (forceRefresh) {
backgroundExecutor.execute(this::doGetAuthTokenForceRefresh);
} else {
backgroundExecutor.execute(this::doGetAuthTokenWithoutForceRefresh);
}
return task;
}

Expand All @@ -256,6 +267,15 @@ public Task<Void> delete() {
return Tasks.call(backgroundExecutor, this::deleteFirebaseInstallationId);
}

private Task<String> addGetIdListener() {
TaskCompletionSource<String> taskCompletionSource = new TaskCompletionSource<>();
StateListener l = new GetIdListener(taskCompletionSource);
synchronized (lock) {
listeners.add(l);
}
return taskCompletionSource.getTask();
}

private Task<InstallationTokenResult> addGetAuthTokenListener() {
TaskCompletionSource<InstallationTokenResult> taskCompletionSource =
new TaskCompletionSource<>();
Expand Down Expand Up @@ -300,17 +320,16 @@ private synchronized String getCacheFid() {
return cachedFid;
}

private String doGetId() {
private final void doGetAuthTokenForceRefresh() {
doRegistrationInternal(true);
}

String fid = getCacheFid();
if (fid != null) {
return fid;
}
PersistedInstallationEntry prefs = getPrefsWithGeneratedIdMultiProcessSafe();
// Execute network calls (CreateInstallations) to the FIS Servers on a separate executor
// i.e networkExecutor
networkExecutor.execute(() -> doNetworkCallIfNecessary(false));
return prefs.getFirebaseInstallationId();
private final void doGetAuthTokenWithoutForceRefresh() {
doRegistrationInternal(false);
}

private final void doGetId() {
doRegistrationInternal(false);
}

/**
Expand All @@ -322,7 +341,8 @@ private String doGetId() {
* @param forceRefresh true if this is for a getAuthToken call and if the caller wants to fetch a
* new auth token from the server even if an unexpired auth token exists on the client.
*/
private void doGetAuthToken(boolean forceRefresh) {
private final void doRegistrationInternal(boolean forceRefresh) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I read the code this does not only do "registration", but also auth token refresh.
Thus, I think the new name is misleading.
How about something that describes what is happening?
Here is a suggestion, maybe you have a better idea.

getLocalDataOrSendRequestToFirebaseInstallationsApi()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a related question: Where do you decide which request to actually send, i.e. #CreateInstallation ("registration") or #GenerateAuthToken ("refresh")?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the below method called doNetworkCallIfNecessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed it to doRegistrationOrRefresh.


PersistedInstallationEntry prefs = getPrefsWithGeneratedIdMultiProcessSafe();

// Since the caller wants to force an authtoken refresh remove the authtoken from the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.firebase.installations;

import com.google.android.gms.tasks.TaskCompletionSource;
import com.google.firebase.installations.local.PersistedInstallationEntry;

class GetIdListener implements StateListener {
final TaskCompletionSource<String> taskCompletionSource;

public GetIdListener(TaskCompletionSource<String> taskCompletionSource) {
this.taskCompletionSource = taskCompletionSource;
}

@Override
public boolean onStateReached(PersistedInstallationEntry persistedInstallationEntry) {
if (persistedInstallationEntry.isUnregistered()
|| persistedInstallationEntry.isRegistered()
|| persistedInstallationEntry.isErrored()) {
taskCompletionSource.trySetResult(persistedInstallationEntry.getFirebaseInstallationId());
return true;
}
return false;
}

@Override
public boolean onException(
PersistedInstallationEntry persistedInstallationEntry, Exception exception) {
return false;
}
}