-
Notifications
You must be signed in to change notification settings - Fork 251
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
feat(auth): Add bulk get/delete methods #365
Conversation
b9c332d
to
9f0c4ee
Compare
9f0c4ee
to
69b37ae
Compare
@@ -171,6 +178,37 @@ UserRecord getUserByPhoneNumber(String phoneNumber) throws FirebaseAuthException | |||
return new UserRecord(response.getUsers().get(0), jsonFactory); | |||
} | |||
|
|||
/** | |||
* @pre identifiers != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are verified in the calling code. (As an alternative, we could just repeat the validation here.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop the pre
annotations. That's not really a convention we use. It is understood that the arguments passed to this class have already been validated. If you want add a class-level javadoc to indicate that explicitly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
* don't run into quota exceeded errors. | ||
*/ | ||
// TODO(rsgowman): When/if the rate limit is relaxed, eliminate this helper. | ||
private ApiFuture<DeleteUsersResult> slowDeleteUsersAsync(List<String> uids) throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to do something similar for the other ports... There seems to be some elasticity such that the full test suite can often pass, but not if you run just the delete users tests in quick succession (as I did while testing).
@@ -0,0 +1,152 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
junit4 doesn't allow nested tests (and therefore doesn't allow nested setup/teardown functions.) The recommendation is to just split into a separate file, which is what I've done here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rsgowman. Looks pretty great. Just pointed out a few tidbits to improve on.
Adding @egilmorez to review the docs portion.
@@ -171,6 +178,37 @@ UserRecord getUserByPhoneNumber(String phoneNumber) throws FirebaseAuthException | |||
return new UserRecord(response.getUsers().get(0), jsonFactory); | |||
} | |||
|
|||
/** | |||
* @pre identifiers != null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop the pre
annotations. That's not really a convention we use. It is understood that the arguments passed to this class have already been validated. If you want add a class-level javadoc to indicate that explicitly.
src/main/java/com/google/firebase/auth/internal/GetAccountInfoRequest.java
Outdated
Show resolved
Hide resolved
|
||
/** | ||
* Returns the number of users that were deleted successfully (possibly zero). Users that did | ||
* not exist prior to calling deleteUsersAsync() will be considered to be successfully |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest code font/link for the method and present tense:
{@link deleteUsersAsync()} are considered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* <p>There are no ordering guarantees; in particular, the nth entry in the users result list is | ||
* not guaranteed to correspond to the nth entry in the input parameters list. | ||
* | ||
* <p>Only a maximum of 100 identifiers may be supplied. If more than 100 identifiers are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest just "A maximum . . . "
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* not guaranteed to correspond to the nth entry in the input parameters list. | ||
* | ||
* <p>Only a maximum of 100 identifiers may be supplied. If more than 100 identifiers are | ||
* supplied, this method will immediately throw an IllegalArgumentException. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest "this method throws an {@link ...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* <p>There are no ordering guarantees; in particular, the nth entry in the users result list is | ||
* not guaranteed to correspond to the nth entry in the input parameters list. | ||
* | ||
* <p>Only a maximum of 100 identifiers may be supplied. If more than 100 identifiers are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we say "specified" above, this should probably work that way too.
Same on the present tense/link format in line 635.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done/done.
* Non-existing users will be considered to be successfully deleted, and will therefore be counted | ||
* in the DeleteUsersResult.getSuccessCount() value. | ||
* | ||
* <p>Only a maximum of 1000 identifiers may be supplied. If more than 1000 identifiers are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar changes here and next line as in 634 and 635.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done/done.
} | ||
|
||
/** | ||
* Set of user records, corresponding to the set of users that were requested. Only users |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest omitting this comma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
import java.util.List; | ||
|
||
/** | ||
* Represents the response from identity toolkit for a batch delete request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be "the identity toolkit?"
The article would normally be omitted only if this is a name, like uppercase "Identity Toolkit"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe? I think I just copied it from UploadAccountResponse. Other locations use 'Google identity toolkit' (HttpErrorResponse, GetAccountInfoResponse, DownloadAccountResponse.) FirebaseUserManager uses 'Google Identity Toolkit'.
I've switched to 'Google Identity Toolkit'.
(Though note that this is an internal object, so shouldn't show up in the public api docs regardless.)
@Key("message") | ||
private String message; | ||
|
||
// A 'localId' field also exists here, but is not currently exposed in the admin sdk. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest caps for "Admin SDK."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
.setPassword("password")); | ||
|
||
try { | ||
// New users should not have a lastRefreshTimestamp set. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't a javadoc comment; is it conventional to use these types of annotations for inline docs like this?
i.e.: clang-format src/test/java/com/google/firebase/auth/FirebaseAuthIT.java \ --lines=140:215 --lines=328:356 --lines=822:838 -i
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @rsgowman. LGTM 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments, otherwise LGTM (reviewing on behalf of egilmore@).
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Gets a page of users starting from the specified {@code pageToken}. Page size will be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Page size is limited to..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/** | ||
* Deletes the users specified by the given identifiers. | ||
* | ||
* <p>Deleting a non-existing user won't generate an error. (i.e. this method is idempotent.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest:
"Deleting a non-existing user does not generate an error (the method is idempotent). Non-existing users are considered to be successfully deleted and are therefore included in the DeleteUsersResult.getSuccessCount()
value."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* <p>A maximum of 1000 identifiers may be supplied. If more than 1000 identifiers are | ||
* supplied, this method throws an {@link IllegalArgumentException}. | ||
* | ||
* <p>This API is currently rate limited at the server to 1 QPS. If you exceed this, you may get a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest:
"This API has a rate limit of 1 QPS. Exceeding the limit may result in a quota exceeded error. If you want to delete more than 1000 users, we suggest adding a delay to ensure you don't exceed the limit."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
}; | ||
} | ||
|
||
/** | ||
* Imports the provided list of users into Firebase Auth. At most 1000 users can be imported at a | ||
* time. This operation is optimized for bulk imports and will ignore checks on identifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest:
"Imports the provided list of users into Firebase Auth. You can import a maximum of 1000 users at a time. This operation is optimized for bulk imports and ignores checks on user identifiers."
(Not completely sure about the user identifiers part, I'm assuming that's what the operation would've checked for)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the first two sentences as per your suggestion. I've changed the last to "This operation is optimized for bulk imports and does not check identifier uniqueness which could result in duplications".
import java.util.List; | ||
|
||
/** | ||
* Represents the request to lookup account information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"look up" (verb)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
assertEquals(0, result.getFailureCount()); | ||
assertTrue(result.getErrors().isEmpty()); | ||
|
||
// Delete the user again, ensuring that everything still counts as a success. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest: "Delete the user again to ensure that..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
} | ||
|
||
/** | ||
* The {@code batchDelete} endpoint is currently rate limited to 1qps. Use this test helper to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The {@code batchDelete} endpoint has a rate limit of 1 QPS. Use this test helper to ensure you don't exceed the quota."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
* Bump netty.version from 4.1.34.Final to 4.1.45.Final (#373) Bumps `netty.version` from 4.1.34.Final to 4.1.45.Final. Updates `netty-codec-http` from 4.1.34.Final to 4.1.45.Final - [Release notes](https://github.com/netty/netty/releases) - [Commits](netty/netty@netty-4.1.34.Final...netty-4.1.45.Final) Updates `netty-handler` from 4.1.34.Final to 4.1.45.Final - [Release notes](https://github.com/netty/netty/releases) - [Commits](netty/netty@netty-4.1.34.Final...netty-4.1.45.Final) Updates `netty-transport` from 4.1.34.Final to 4.1.45.Final - [Release notes](https://github.com/netty/netty/releases) - [Commits](netty/netty@netty-4.1.34.Final...netty-4.1.45.Final) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(auth): Add bulk get/delete methods (#365) This PR allows callers to retrieve a list of users by unique identifier (uid, email, phone, federated provider uid) as well as to delete a list of users. RELEASE NOTE: Added getUsers() and deleteUsers() APIs for retrieving and deleting user accounts in bulk. * chore: Setting the version of the Maven Javadoc plugin (#412) * [chore] Release 6.13.0 (#413) * [chore] Release 6.13.0 take 2 (#414) * Upgated the gpg keys * Added temp verify script * Disabled tty for gpg import * Removing temp verification script * Updated publish commands * [chore] Release 6.13.0 take 3 (#415) * [chore] Release 6.13.0 take 4 (#416) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rsgowman <rich@gowman.noip.me>
This PR allows callers to retrieve a list of users by unique identifier (uid, email, phone, federated provider uid) as well as to delete a list of users.
RELEASE NOTE: Added
getUsers()
anddeleteUsers()
APIs for retrieving and deleting user accounts in bulk.