GMS Task class: can getResult() return null if isSuccessful()?
There is recently a @Nullable change to GMS tasks library. The first few lines of decompiled .class looks like
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
Previously my Kotlin code compiled:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
After updating some gms play-services-zzz
dependencies the code now has compile error:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
The question is, does isSuccessful() == true
imply that getResult != null
? Or would it just be better to change the if test to if (task.result != null)
?
android kotlin google-play-services
add a comment |
There is recently a @Nullable change to GMS tasks library. The first few lines of decompiled .class looks like
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
Previously my Kotlin code compiled:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
After updating some gms play-services-zzz
dependencies the code now has compile error:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
The question is, does isSuccessful() == true
imply that getResult != null
? Or would it just be better to change the if test to if (task.result != null)
?
android kotlin google-play-services
add a comment |
There is recently a @Nullable change to GMS tasks library. The first few lines of decompiled .class looks like
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
Previously my Kotlin code compiled:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
After updating some gms play-services-zzz
dependencies the code now has compile error:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
The question is, does isSuccessful() == true
imply that getResult != null
? Or would it just be better to change the if test to if (task.result != null)
?
android kotlin google-play-services
There is recently a @Nullable change to GMS tasks library. The first few lines of decompiled .class looks like
public abstract class Task<TResult> {
public Task() {
}
public abstract boolean isComplete();
public abstract boolean isSuccessful();
public abstract boolean isCanceled();
@Nullable
public abstract TResult getResult();
Previously my Kotlin code compiled:
if (task.isSuccessful) {
task.result.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
}
After updating some gms play-services-zzz
dependencies the code now has compile error:
LoginActivity.kt: (148, 28): Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type AuthResult?
The question is, does isSuccessful() == true
imply that getResult != null
? Or would it just be better to change the if test to if (task.result != null)
?
android kotlin google-play-services
android kotlin google-play-services
asked Nov 13 '18 at 22:08
androidguyandroidguy
8171613
8171613
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
What you are seeing is the Kotlin compiler failing to smart-cast the result to a NonNull type based on the result of isSuccessful, this can happen when interacting with both Java and Kotlin code.
In Kotlin 1.3 an implementation of "Contracts" was added to the language to allow developers to add meta data about a method in a format that the IDE can use to statically analyze and infer type (smart-cast).
See Section 1.2 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
So with contracts it would correctly smart-cast if the implementation looked like this:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
In your case however you probably want to throw on another safe call operator ?
and call your !task.isSuccessful
code with the Elvis operator ?:
like this:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290241%2fgms-tasktresult-class-can-getresult-return-null-if-issuccessful%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
What you are seeing is the Kotlin compiler failing to smart-cast the result to a NonNull type based on the result of isSuccessful, this can happen when interacting with both Java and Kotlin code.
In Kotlin 1.3 an implementation of "Contracts" was added to the language to allow developers to add meta data about a method in a format that the IDE can use to statically analyze and infer type (smart-cast).
See Section 1.2 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
So with contracts it would correctly smart-cast if the implementation looked like this:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
In your case however you probably want to throw on another safe call operator ?
and call your !task.isSuccessful
code with the Elvis operator ?:
like this:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
add a comment |
What you are seeing is the Kotlin compiler failing to smart-cast the result to a NonNull type based on the result of isSuccessful, this can happen when interacting with both Java and Kotlin code.
In Kotlin 1.3 an implementation of "Contracts" was added to the language to allow developers to add meta data about a method in a format that the IDE can use to statically analyze and infer type (smart-cast).
See Section 1.2 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
So with contracts it would correctly smart-cast if the implementation looked like this:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
In your case however you probably want to throw on another safe call operator ?
and call your !task.isSuccessful
code with the Elvis operator ?:
like this:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
add a comment |
What you are seeing is the Kotlin compiler failing to smart-cast the result to a NonNull type based on the result of isSuccessful, this can happen when interacting with both Java and Kotlin code.
In Kotlin 1.3 an implementation of "Contracts" was added to the language to allow developers to add meta data about a method in a format that the IDE can use to statically analyze and infer type (smart-cast).
See Section 1.2 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
So with contracts it would correctly smart-cast if the implementation looked like this:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
In your case however you probably want to throw on another safe call operator ?
and call your !task.isSuccessful
code with the Elvis operator ?:
like this:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
What you are seeing is the Kotlin compiler failing to smart-cast the result to a NonNull type based on the result of isSuccessful, this can happen when interacting with both Java and Kotlin code.
In Kotlin 1.3 an implementation of "Contracts" was added to the language to allow developers to add meta data about a method in a format that the IDE can use to statically analyze and infer type (smart-cast).
See Section 1.2 "Returns and Implies" https://proandroiddev.com/kotlin-contracts-make-great-deals-with-the-compiler-f524e57f11c
So with contracts it would correctly smart-cast if the implementation looked like this:
open class Task<T> {
var result: T? = null
private set
fun isSuccessful(): Boolean {
contract {
returns(true) implies (result != null)
}
return result != null
}
}
In your case however you probably want to throw on another safe call operator ?
and call your !task.isSuccessful
code with the Elvis operator ?:
like this:
if (task.isSuccessful) {
task.result?.user?.getIdToken(false)?.addOnCompleteListener { taskk ->
this.emailIdTokenCompleteListener()(taskk)
} ?: handleFailure() // Defensively call just in case
} else {
handleFailure()
}
answered Nov 13 '18 at 22:36
waterPoweredMonkeywaterPoweredMonkey
594
594
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53290241%2fgms-tasktresult-class-can-getresult-return-null-if-issuccessful%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown