"Query did not return a unique result" when doing Facebook Login

Hi there,

Just today, I started getting this “Query did not return a unique result” error when trying to Log in with Facebook in my app. A user reported it first, I checked the Users table, and there were no duplicates. I tried to reproduce this issue by logging into my app with my own Facebook account and I got the exact same error. Checked the Users table and found no duplicates either.

It said in the error that an internal trouble ticket was created. Here are a couple I noted down that relate to this:

  • 20426F72-950BA445-FF4D-FD97DA8D8E00
  • 8E7CF1C4-5EBCACE8-FF8E-CD770004C000

Hope that helps in debugging that issue. I would really appreciate some help on this.

PS: By “checking for duplicates”, I meant checking for similar names/email and objectId in the User table. Also, if it makes any difference, I haven’t changed anything at all on the Facebook developer console. Everything has been running exactly like this for over a year without issues, until today.

Thanks in advance!

Hi, @Jeffrey_Sera

I was unable to reproduce your problem in my app. Despite, we will be happy to assist you. Could you please provide your App ID and steps to reproduce your problem.

Cases I tried in my app:
Case 1: Login to the app using emailA - login is successful;
Case 2: Re login to the app using emailA - login is successful;
Case 3: Change user data in the Backendless app and re login using emailA - login is successful;
Case 4: Login to the app using emailB - login is successful;

Regards,
Marina

Hey there @Marina.Kan !

I’m not sure exactly what’s going on either. After some debugging, it seems the actual logging in with Facebook works correctly, but it is after that when it fails, when I try to pass the access token to Baackendless using this function (Example below is with the Android SDK):

Backendless.UserService.loginWithFacebookSdk(token, callback);

In this function, the handleFault(); callback is always triggered.

My App ID is: 4E54F8C8-0A73-E26C-FFCB-5C6E36D78C00

Thanks again!

We are investigating your issue.

Regards,
Marina

Hi @Jeffrey_Sera

Unfortunately we couldn’t reproduce your issue. Login with Facebook works fine for other apps. Also we haven’t made any significant changes that can affect it.
I also logged in with Facebook into your app and the user record was successfully created.

Can you please provide the following information to help us to debug and reproduce the issue:

  • the code sample you use to login users with Facebook
  • full stacktrace for the error you get
  • the access token for your facebook account, you cannot login with?

Best Regards,
Maksym

Hello @Maksym_Khobotin2,

I’ve tried updating my Backendless SDK to the latest version, but an issue still occurs. It looks like the Backendless.UserService.loginWithFacebookSdk has already been removed, and in its place there is this a new function:

Backendless.UserService.loginWithOAuth2

It still fails at this method, but the error message is now different:

Not existing user token - C7A386A7-3EDD-4095-A0F6-24B96E4EFCFF. Relogin user to update your user token

Here is the code I use to login users to Facebook, and then the code to connect the account to Backendless:

private void loginWithFacebook(){
    final ProgressDialog fbLoading = new ProgressDialog(LoginActivity.this);
    fbLoading.setCancelable(false);
    fbLoading.setMessage(getResources().getString(R.string.login_loading));
    fbLoading.show();

    LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(final LoginResult loginResult) {
            GraphRequest request = GraphRequest.newMeRequest(loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
                @Override
                public void onCompleted(JSONObject object, GraphResponse response) {
                    Log.d("access token", loginResult.getAccessToken().getToken());
                    Log.d("permissions granted", loginResult.getRecentlyGrantedPermissions().toString());
                    Log.d("permissions denied", loginResult.getRecentlyDeniedPermissions().toString());
                    connectFacebookToBackendless(loginResult.getAccessToken(), fbLoading);
                }
            });
            request.executeAsync();
        }

        @Override
        public void onCancel() {
            fbLoading.dismiss();
        }

        @Override
        public void onError(FacebookException error) {
            fbLoading.dismiss();
            Toast.makeText(LoginActivity.this, getResources().getString(R.string.error), Toast.LENGTH_LONG).show();
        }
    });
    LoginManager.getInstance().logIn(LoginActivity.this, Arrays.asList("public_profile", "email"));
}


private void connectFacebookToBackendless(AccessToken token, final ProgressDialog dialog) {

    Map<String, String> fields = new HashMap<>();
    fields.put("name", "name");
    fields.put("email", "email");
    fields.put("id", "fbId");

    Backendless.UserService.loginWithOAuth2("facebook", token.getToken(), fields, new AsyncCallback<BackendlessUser>() {
        @Override
        public void handleResponse(BackendlessUser user) {
            UserData.saveUserData(LoginActivity.this, user);

            if (UserData.getProfileImageUrl(LoginActivity.this) == null || UserData.getProfileImageUrl(LoginActivity.this).isEmpty()) {

                user.setProperty("profileImageUrl", "https://graph.facebook.com/" + UserData.getUserFbId(LoginActivity.this) + "/picture?type=large");

                Backendless.Data.of(BackendlessUser.class).save(user, new AsyncCallback<BackendlessUser>() {
                    @Override
                    public void handleResponse(BackendlessUser response) {
                        UserData.saveUserData(LoginActivity.this, response);
                        dialog.dismiss();
                        goToMainActivity();
                    }

                    @Override
                    public void handleFault(BackendlessFault fault) {
                        dialog.dismiss();
                        goToMainActivity();
                    }
                });

            } else {
                dialog.dismiss();
                goToMainActivity();
            }
        }

        @Override
        public void handleFault(BackendlessFault fault) {
            dialog.dismiss();
            Log.d("error", fault.getMessage());
            Toast.makeText(LoginActivity.this, fault.getMessage(), Toast.LENGTH_LONG).show();
        }
    }, true);
}

The only stacktrace I can find that could be relevant is this:

Could not unregister device on Backendless server: BackendlessFault{ code: '3064', message: 'Not existing user token - C7A386A7-3EDD-4095-A0F6-24B96E4EFCFF. Relogin user to update your user token', detail: 'Not existing user token - C7A386A7-3EDD-4095-A0F6-24B96E4EFCFF. Relogin user to update your user token', extendedData: '{}' }

@Maksym_Khobotin2

OK, according to an old thread, that “Not existing user token” error (in the post above) could be fixed by calling Backendless.UserService.Logout in case of login failure. I did just that, and I got through that error, but am now stuck with the “query did not return a unique result” again. I tried with a Facebook account that was already registered in our app, as well as a new Facebook account. In both cases, the issue persists.

Here is the stack trace.

javax.persistence.NonUniqueResultException: query did not return a unique result: 2
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:128)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1588)
at com.backendless.datamodel.application.dao.SocialUserDao.lambda$findBySocialIdAndUserTypeId$0(SocialUserDao.java:33)
at com.backendless.datamodel.dao.JpaContext.executeAppSync(JpaContext.java:125)
at com.backendless.datamodel.dao.JpaContextService.executeAppSync(JpaContextService.java:39)
at com.backendless.datamodel.application.dao.SocialUserDao.findBySocialIdAndUserTypeId(SocialUserDao.java:27)
at com.backendless.datamodel.application.dao.SocialUserDao.lambda$findBySocialIdAndUserTypeId$1(SocialUserDao.java:44)
at com.backendless.datamodel.dao.JpaContext.executeAppSync(JpaContext.java:125)
at com.backendless.datamodel.dao.JpaContext.lambda$executeApp$0(JpaContext.java:150)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Suppressed: java.util.concurrent.ExecutionException: javax.persistence.NonUniqueResultException: query did not return a unique result: 2
	at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
	at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1999)
	at com.backendless.async.UncheckedCompletableFutureImpl.getUnchecked(UncheckedCompletableFutureImpl.java:158)
	at com.backendless.services.users.services.social.auth.AuthenticationService.authenticate(AuthenticationService.java:57)
	at com.backendless.services.users.services.social.auth.OAuth2AuthenticationService.authenticate(OAuth2AuthenticationService.java:42)
	at com.backendless.services.users.impl.UserServiceClientsProxyOrigin.loginWithOAuth2(UserServiceClientsProxyOrigin.java:610)
	at com.backendless.services.users.impl.UserServiceClientsProxyOrigin$$EnhancerByGuice$$c07ba30.CGLIB$loginWithOAuth2$22(<generated>)
	at com.backendless.services.users.impl.UserServiceClientsProxyOrigin$$EnhancerByGuice$$c07ba30$$FastClassByGuice$$4aef6ff4.invoke(<generated>)
	at com.google.inject.internal.cglib.proxy.$MethodProxy.invokeSuper(MethodProxy.java:228)
	at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:76)
	at com.backendless.inject.interceptors.AbstractApiCallInterceptor.lambda$invoke$0(AbstractApiCallInterceptor.java:50)
	at com.backendless.services.RunnerService.executeApiCall(RunnerService.java:56)
	at com.backendless.inject.interceptors.AbstractApiCallInterceptor.invoke(AbstractApiCallInterceptor.java:47)
	at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:78)
	at com.backendless.services.users.services.social.ReportRegisterAnalyticInterceptor.invoke(ReportRegisterAnalyticInterceptor.java:29)
	at com.google.inject.internal.InterceptorStackCallback$InterceptedMethodInvocation.proceed(InterceptorStackCallback.java:78)
	at com.google.inject.internal.InterceptorStackCallback.intercept(InterceptorStackCallback.java:54)
	at com.backendless.services.users.impl.UserServiceClientsProxyOrigin$$EnhancerByGuice$$c07ba30.loginWithOAuth2(<generated>)
	at controllers.Social.oAuth2Login(Social.java:317)
	at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$1153(Routes.scala:13851)
	at play.core.routing.HandlerInvokerFactory$$anon$8.resultCall(HandlerInvoker.scala:150)
	at play.core.routing.HandlerInvokerFactory$$anon$8.resultCall(HandlerInvoker.scala:149)
	at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$3$$anon$4$$anon$5.invocation(HandlerInvoker.scala:115)
	at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:119)
	at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:33)
	at com.backendless.old.security.OriginAction.call(OriginAction.java:48)
	at com.backendless.old.security.ValidateApplication.call(ValidateApplication.java:75)
	at com.backendless.old.security.ApplicationExistenceAndUseAction.call(ApplicationExistenceAndUseAction.java:38)
	at com.backendless.old.security.ConsiderApiCallAction.call(ConsiderApiCallAction.java:29)
	at com.backendless.TimeOutAction.call(TimeOutAction.java:28)
	at com.backendless.old.security.SuperScalingAction.lambda$call$0(SuperScalingAction.java:26)
	at com.backendless.services.billing.superscaling.SuperScalingManager.applyWithPolicies(SuperScalingManager.java:59)
	at com.backendless.old.security.SuperScalingAction.call(SuperScalingAction.java:26)
	at com.backendless.ApiCallLimitAction.call(ApiCallLimitAction.java:26)
	at com.backendless.ApiCallAction.call(ApiCallAction.java:15)
	at com.backendless.StaticHttpResponseHeadersAction.call(StaticHttpResponseHeadersAction.java:22)
	at com.backendless.StackOverflowHandlerAction.call(StackOverflowHandlerAction.java:21)
	at com.backendless.CloseEntityManagerAction.call(CloseEntityManagerAction.java:36)
	at com.backendless.CurrentRequestsNumberAction.call(CurrentRequestsNumberAction.java:31)
	at com.backendless.ContextInitAction.call(ContextInitAction.java:19)
	at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:175)
	at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659)
	at scala.util.Success.$anonfun$map$1(Try.scala:255)
	at scala.util.Success.map(Try.scala:213)
	at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
	at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
	at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
	at play.core.j.HttpExecutionContext.$anonfun$execute$1(HttpExecutionContext.scala:64)
	at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
	at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:59)
	at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:72)
	at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:372)
	at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:371)
	at scala.concurrent.impl.Promise$KeptPromise$Successful.onComplete(Promise.scala:379)
	at scala.concurrent.impl.Promise.transform(Promise.scala:33)
	at scala.concurrent.impl.Promise.transform$(Promise.scala:31)
	at scala.concurrent.impl.Promise$KeptPromise$Successful.transform(Promise.scala:379)
	at scala.concurrent.Future.map(Future.scala:292)
	at scala.concurrent.Future.map$(Future.scala:292)
	at scala.concurrent.impl.Promise$KeptPromise$Successful.map(Promise.scala:379)
	at scala.concurrent.Future$.apply(Future.scala:659)
	at play.core.j.JavaAction.apply(JavaAction.scala:176)
	at play.api.mvc.Action.$anonfun$apply$4(Action.scala:82)
	at scala.concurrent.Future.$anonfun$flatMap$1(Future.scala:307)
	at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)
	at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
	at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:56)
	at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:93)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:85)
	at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:93)
	at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:48)
	... 3 more

Hi @Jeffrey_Sera!

Your last 2 messages were very helpfull.

Your error caused by your fields mappings, by “id” => “fbId” if to be more specific. If you set mapping for this field to “id” => “id” or just remove it then everything will work as expected. Facebook user ID will be stored in “id” column. If you still want your column “fbId” populated with identifier from Facebook you can create this column as generated column and specify “id” as expression.

Could you please write back if my advice has worked for four case?

Meanwhile we will investigate how to add support for custom mappings for this field

Also for the case

I have created an internal ticket to ignore previous user token BKNDLSS-23750

Regards, Andriy

@Jeffrey_Sera,

I have created internal ticket BKNDLSS-23751 to add support for overriding mappings for this field. We will notify you when fix will be released.

Regards, Andriy

Hello @Andriy_Konoz

The fix you suggested works! I’ve made this change and uploaded new versions of our app to the App Store and Play Store. Now hoping for a quick turnaround. Strange though that this bit of code has already been there for over a year and only started causing issues recently.

In any case, I really appreciate your help on the matter. :pray:

Hello @Jeffrey_Sera

We’ve just updated cloud servers with a fix for the issue you described above. Could you kindly let us know whether fix works for you well?

Regards,
Inna