Skip to content

Commit 44687d3

Browse files
jonsimantova-maurice
authored andcommitted
If an error occurs while creating a credential, pass through an error
code/message to the sign-in Future that is ultimately returned when we try to sign in with that credential. Currently only affects EmailAuthProvider on Android, but can be used by other credentials in the future. (Changes to iOS and Desktop are to properly copy the error_code_ and error_message_ in the copy constructor and assignment operator). PiperOrigin-RevId: 249327161
1 parent 7bc7198 commit 44687d3

File tree

5 files changed

+82
-28
lines changed

5 files changed

+82
-28
lines changed

auth/src/android/auth_android.cc

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,9 @@ void Auth::DestroyPlatformAuth(AuthData* auth_data) {
279279
auth::GetMethodId(auth::kRemoveAuthStateListener),
280280
static_cast<jobject>(auth_data->listener_impl));
281281
assert(env->ExceptionCheck() == false);
282-
env->CallVoidMethod(static_cast<jobject>(auth_data->id_token_listener_impl),
283-
jni_id_token_listener::GetMethodId(
284-
jni_id_token_listener::kDisconnect));
282+
env->CallVoidMethod(
283+
static_cast<jobject>(auth_data->id_token_listener_impl),
284+
jni_id_token_listener::GetMethodId(jni_id_token_listener::kDisconnect));
285285
assert(env->ExceptionCheck() == false);
286286
env->CallVoidMethod(AuthImpl(auth_data),
287287
auth::GetMethodId(auth::kRemoveIdTokenListener),
@@ -400,14 +400,20 @@ Future<User*> Auth::SignInWithCredential(const Credential& credential) {
400400
const auto handle = futures.SafeAlloc<User*>(kAuthFn_SignInWithCredential);
401401
JNIEnv* env = Env(auth_data_);
402402

403-
jobject pending_result = env->CallObjectMethod(
404-
AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential),
405-
CredentialFromImpl(credential.impl_));
406-
407-
if (!CheckAndCompleteFutureOnError(env, &futures, handle)) {
408-
RegisterCallback(pending_result, handle, auth_data_,
409-
ReadUserFromSignInResult);
410-
env->DeleteLocalRef(pending_result);
403+
// If the credential itself is in an error state, don't try signing in.
404+
if (credential.error_code_ != kAuthErrorNone) {
405+
futures.Complete(handle, credential.error_code_,
406+
credential.error_message_.c_str());
407+
} else {
408+
jobject pending_result = env->CallObjectMethod(
409+
AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential),
410+
CredentialFromImpl(credential.impl_));
411+
412+
if (!CheckAndCompleteFutureOnError(env, &futures, handle)) {
413+
RegisterCallback(pending_result, handle, auth_data_,
414+
ReadUserFromSignInResult);
415+
env->DeleteLocalRef(pending_result);
416+
}
411417
}
412418
return MakeFuture(&futures, handle);
413419
}
@@ -419,13 +425,19 @@ Future<SignInResult> Auth::SignInAndRetrieveDataWithCredential(
419425
kAuthFn_SignInAndRetrieveDataWithCredential);
420426
JNIEnv* env = Env(auth_data_);
421427

422-
jobject pending_result = env->CallObjectMethod(
423-
AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential),
424-
CredentialFromImpl(credential.impl_));
425-
426-
if (!CheckAndCompleteFutureOnError(env, &futures, handle)) {
427-
RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult);
428-
env->DeleteLocalRef(pending_result);
428+
// If the credential itself is in an error state, don't try signing in.
429+
if (credential.error_code_ != kAuthErrorNone) {
430+
futures.Complete(handle, credential.error_code_,
431+
credential.error_message_.c_str());
432+
} else {
433+
jobject pending_result = env->CallObjectMethod(
434+
AuthImpl(auth_data_), auth::GetMethodId(auth::kSignInWithCredential),
435+
CredentialFromImpl(credential.impl_));
436+
437+
if (!CheckAndCompleteFutureOnError(env, &futures, handle)) {
438+
RegisterCallback(pending_result, handle, auth_data_, ReadSignInResult);
439+
env->DeleteLocalRef(pending_result);
440+
}
429441
}
430442
return MakeFuture(&futures, handle);
431443
}

auth/src/android/credential_android.cc

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,10 @@ Credential::~Credential() {
273273
}
274274
}
275275

276-
Credential::Credential(const Credential& rhs) : impl_(nullptr) { *this = rhs; }
276+
Credential::Credential(const Credential& rhs)
277+
: impl_(nullptr), error_code_(kAuthErrorNone) {
278+
*this = rhs;
279+
}
277280

278281
// Increase the reference count when copying.
279282
Credential& Credential::operator=(const Credential& rhs) {
@@ -284,6 +287,8 @@ Credential& Credential::operator=(const Credential& rhs) {
284287
} else {
285288
impl_ = nullptr;
286289
}
290+
error_code_ = rhs.error_code_;
291+
error_message_ = rhs.error_message_;
287292
return *this;
288293
}
289294

@@ -324,11 +329,33 @@ Credential EmailAuthProvider::GetCredential(const char* email,
324329
jobject j_cred = env->CallStaticObjectMethod(
325330
emailcred::GetClass(), emailcred::GetMethodId(emailcred::kGetCredential),
326331
j_email, j_password);
327-
if (firebase::util::CheckAndClearJniExceptions(env)) j_cred = nullptr;
328332
env->DeleteLocalRef(j_email);
329333
env->DeleteLocalRef(j_password);
334+
AuthError error_code = kAuthErrorNone;
335+
std::string error_message;
336+
if (!j_cred) {
337+
// Read error from exception, except give more specific errors for email and
338+
// password being blank.
339+
if (strlen(email) == 0) {
340+
firebase::util::CheckAndClearJniExceptions(env);
341+
error_code = kAuthErrorMissingEmail;
342+
error_message = "An email address must be provided.";
343+
} else if (strlen(password) == 0) {
344+
firebase::util::CheckAndClearJniExceptions(env);
345+
error_code = kAuthErrorMissingPassword;
346+
error_message = "A password must be provided.";
347+
} else {
348+
error_code = CheckAndClearJniAuthExceptions(env, &error_message);
349+
}
350+
}
330351

331-
return Credential(CredentialLocalToGlobalRef(j_cred));
352+
Credential cred = Credential(CredentialLocalToGlobalRef(j_cred));
353+
if (!j_cred) {
354+
cred.error_code_ = error_code;
355+
cred.error_message_ = error_message;
356+
}
357+
358+
return cred;
332359
}
333360

334361
// static

auth/src/desktop/credential_desktop.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#include "auth/src/include/firebase/auth/credential.h"
16-
1715
#include "app/src/assert.h"
1816
#include "auth/src/desktop/auth_credential.h"
1917
#include "auth/src/desktop/credential_impl.h"
18+
#include "auth/src/include/firebase/auth/credential.h"
2019

2120
namespace firebase {
2221
namespace auth {
@@ -27,6 +26,8 @@ Credential::Credential(const Credential& rhs) : impl_(nullptr) {
2726
if (rhs.impl_) {
2827
impl_ = new CredentialImpl(*(static_cast<CredentialImpl*>(rhs.impl_)));
2928
}
29+
error_code_ = rhs.error_code_;
30+
error_message_ = rhs.error_message_;
3031
}
3132

3233
Credential& Credential::operator=(const Credential& rhs) {
@@ -37,6 +38,9 @@ Credential& Credential::operator=(const Credential& rhs) {
3738
impl_ = new CredentialImpl(*(static_cast<CredentialImpl*>(rhs.impl_)));
3839
}
3940

41+
error_code_ = rhs.error_code_;
42+
error_message_ = rhs.error_message_;
43+
4044
return *this;
4145
}
4246

auth/src/include/firebase/auth/credential.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@
1818
#define FIREBASE_AUTH_CLIENT_CPP_SRC_INCLUDE_FIREBASE_AUTH_CREDENTIAL_H_
1919

2020
#include <stdint.h>
21+
2122
#include <string>
23+
2224
#include "firebase/internal/common.h"
25+
#include "firebase/auth/types.h"
2326

2427
namespace firebase {
2528

2629
// Predeclarations.
2730
class App;
2831

29-
template<typename T>
32+
template <typename T>
3033
class Future;
3134

3235
namespace auth {
@@ -68,10 +71,10 @@ class Credential {
6871
/// @see EmailAuthProvider::GetCredential()
6972
/// @see FacebookAuthProvider::GetCredential()
7073
/// @see GoogleAuthProvider::GetCredential()
71-
explicit Credential(void* impl) : impl_(impl) {}
74+
explicit Credential(void* impl) : impl_(impl), error_code_(kAuthErrorNone) {}
7275

7376
public:
74-
Credential() : impl_(NULL) {}
77+
Credential() : impl_(nullptr), error_code_(kAuthErrorNone) {}
7578
~Credential();
7679

7780
/// Copy constructor.
@@ -97,16 +100,20 @@ class Credential {
97100
/// @returns True if the credential is valid, false otherwise.
98101
bool is_valid() const;
99102

100-
/// @cond FIREBASE_APP_INTERNAL
101103
protected:
102104
/// @cond FIREBASE_APP_INTERNAL
103105
friend class Auth;
104106
friend class User;
105-
/// @endcond
106107

107108
/// Platform-specific implementation.
108109
/// For example, FIRAuthCredential* on iOS.
109110
void* impl_;
111+
112+
// If not kAuthErrorNone, then use this error code and string to override
113+
// whatever error we would normally return when trying to sign-in with this
114+
// credential.
115+
AuthError error_code_;
116+
std::string error_message_;
110117
/// @endcond
111118
};
112119

auth/src/ios/credential_ios.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ @implementation PhoneListenerDataObjC
6262
if (rhs.impl_ != NULL) {
6363
impl_ = new FIRAuthCredentialPointer(CredentialFromImpl(rhs.impl_));
6464
}
65+
error_code_ = rhs.error_code_;
66+
error_message_ = rhs.error_message_;
6567
}
6668

6769
// Default assigment.
@@ -70,6 +72,8 @@ @implementation PhoneListenerDataObjC
7072
delete static_cast<FIRAuthCredentialPointer*>(impl_);
7173
impl_ = new FIRAuthCredentialPointer(CredentialFromImpl(rhs.impl_));
7274
}
75+
error_code_ = rhs.error_code_;
76+
error_message_ = rhs.error_message_;
7377
return *this;
7478
}
7579

0 commit comments

Comments
 (0)