Flutter app crashes on concurrent transactions performed on cloud Firestore - firebase

I am trying to develop an app where multiple users log in and completes a poll concurrently.
In this, as soon as user submits the answer the transaction is ran to increment the counter for given answer
try {
DocumentSnapshot freshsnap = await tx.get(reff);
try {
await tx.update(reff, <String, dynamic>{
'$i': freshsnap['$i'] + 1,
});
} catch (error) {
print("Error" + error.code);
}
} catch (error) {
if (error is PlatformException &&
error.code == 'Error performing transaction') {
// await tx.set(ref, data);
print("Error" + error.code);
} else
rethrow;
}
}).catchError((onError){
print("Error on: "+onError);
});
as soon as the multiple users submit the same answer for same question concurrently i.e The same field in same document is requested to update by multiple users concurrently the app crashes and generates following error:
FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(12169): Process: com.rrcg.tumerboared, PID: 12169
E/AndroidRuntime(12169): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime(12169): at android.os.AsyncTask$3.done(AsyncTask.java:354)
E/AndroidRuntime(12169): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
E/AndroidRuntime(12169): at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
E/AndroidRuntime(12169): at java.util.concurrent.FutureTask.run(FutureTask.java:271)
E/AndroidRuntime(12169): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
E/AndroidRuntime(12169): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(12169): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(12169): at java.lang.Thread.run(Thread.java:764)
E/AndroidRuntime(12169): Caused by: java.lang.AssertionError: INTERNAL ASSERTION FAILED: A transaction object cannot be used after its update callback has been invoked.
E/AndroidRuntime(12169): at com.google.firebase.firestore.util.Assert.fail(com.google.firebase:firebase-firestore##21.2.1:46)
E/AndroidRuntime(12169): at com.google.firebase.firestore.util.Assert.hardAssert(com.google.firebase:firebase-firestore##21.2.1:31)
E/AndroidRuntime(12169): at com.google.firebase.firestore.core.Transaction.ensureCommitNotCalled(com.google.firebase:firebase-firestore##21.2.1:246)
E/AndroidRuntime(12169): at com.google.firebase.firestore.core.Transaction.lookup(com.google.firebase:firebase-firestore##21.2.1:81)
E/AndroidRuntime(12169): at com.google.firebase.firestore.Transaction.getAsync(com.google.firebase:firebase-firestore##21.2.1:191)
E/AndroidRuntime(12169): at com.google.firebase.firestore.Transaction.get(com.google.firebase:firebase-firestore##21.2.1:228)
E/AndroidRuntime(12169): at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$5.doInBackground(CloudFirestorePlugin.java:550)
E/AndroidRuntime(12169): at io.flutter.plugins.firebase.cloudfirestore.CloudFirestorePlugin$5.doInBackground(CloudFirestorePlugin.java:545)
E/AndroidRuntime(12169): at android.os.AsyncTask$2.call(AsyncTask.java:333)
E/AndroidRuntime(12169): at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(12169): ... 4 more
Have no idea why is this happening, since transaction should allow multiple users to update a field of a document concurrently.

If you are running on a physical iOS device, the crash is caused by this bug in the FlutterFire binding library. There doesn't seem to be a workaround, so keep an eye on the issue for updates.

I solved this by making the transaction object (tx) non-async and moving the async logic outside the transaction block. After all, the whole point of transactions is to execute its instructions atomically and async instructions kind of defeat this purpose.

Related

How to track when Firebase Functions Task Queues have exhausted all retries?

I am using Firebase Functions Task Queues to call numerous API endpoints.
Each of those functions is set to retry 5 times if they encounter error.
Now I want to track if the function completes successfully or fails completely (i.e. all retries are exhausted and the function still throws an error). I'll probably update a Firestore document when that happens.
For example, here is a Task Queue function, how do I add the above functionality?
export const someTask = functions.tasks
.taskQueue({
retryConfig: {
maxAttempts: 5,
minBackoffSeconds: 60,
},
rateLimits: {
maxConcurrentDispatches: 1,
},
})
.onDispatch(
async () => {
try {
// Call the API
await apiCall();
return;
} catch (error) {
// Throw error so that the Task Queue will retry
throw new functions.https.HttpsError(
'unknown',
'someTask error'
);
}
}
);

Prisma on production - User 'xxx' has exceeded the 'max_user_connections' resource

I'm having an issue when I upload my Next.js app in production (in Vercel). When I run the app in development, it works fine. Only 1 connection is created. But when I use the app in production, instantly reaches the max users connections (5).
I don't know what to share exactly, but this is my client.js:
import { PrismaClient } from "./generators/app";
export const prisma =
global.prisma ||
new PrismaClient();
if (process.env.NODE_ENV !== 'production') global.prisma = prisma;
And this is how I import it from api files:
import { prisma } from "../../../prisma/client";
I've tried both guides:
https://www.prisma.io/docs/guides/performance-and-optimization/connection-management
https://www.prisma.io/docs/guides/database/troubleshooting-orm/help-articles/nextjs-prisma-client-dev-practices
This is the error:
2022-10-27T20:58:32.492Z 07594f4a-727a-4e98-a4aa-264d060dc08b ERROR PrismaClientInitializationError:
Invalid `prisma.user.findUnique()` invocation:
Error querying the database: Server error: `ERROR 42000 (1226): User 'xxx' has exceeded the 'max_user_connections' resource (current value: 5)'
at RequestHandler.handleRequestError (/var/task/.next/server/chunks/7738.js:31215:19)
at RequestHandler.request (/var/task/.next/server/chunks/7738.js:31188:18)
at async PrismaClient._request (/var/task/.next/server/chunks/7738.js:32176:24)
at async havePermission (/var/task/.next/server/chunks/3433.js:49:40)
at async getServerData (/var/task/.next/server/pages/api/app/user/get/[column].js:181:34)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:366:9)
at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:469:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:719:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:247:36)
at async NextNodeServer.run (/var/task/node_modules/next/dist/server/base-server.js:346:29) {
clientVersion: '4.3.1',
errorCode: undefined
}
2022-10-27T20:58:32.501Z 07594f4a-727a-4e98-a4aa-260d060dc08b ERROR PrismaClientInitializationError:
Invalid `prisma.user.findUnique()` invocation:
Error querying the database: Server error: `ERROR 42000 (1226): User 'xxx' has exceeded the 'max_user_connections' resource (current value: 5)'
at RequestHandler.handleRequestError (/var/task/.next/server/chunks/7738.js:31215:19)
at RequestHandler.request (/var/task/.next/server/chunks/7738.js:31188:18)
at async PrismaClient._request (/var/task/.next/server/chunks/7738.js:32176:24)
at async havePermission (/var/task/.next/server/chunks/3433.js:49:40)
at async getServerData (/var/task/.next/server/pages/api/app/user/get/[column].js:181:34)
at async Object.apiResolver (/var/task/node_modules/next/dist/server/api-utils/node.js:366:9)
at async NextNodeServer.runApi (/var/task/node_modules/next/dist/server/next-server.js:469:9)
at async Object.fn (/var/task/node_modules/next/dist/server/next-server.js:719:37)
at async Router.execute (/var/task/node_modules/next/dist/server/router.js:247:36)
at async NextNodeServer.run (/var/task/node_modules/next/dist/server/base-server.js:346:29) {
clientVersion: '4.3.1',
errorCode: undefined
}
RequestId: 07594f4a-727a-4e98-a4aa-264d060dc08b Error: Runtime exited with error: exit status 1
Runtime.ExitError
After that it tries every second to make a GET request to the api with 500 response.
Vercel by default creates like 5 new connections to the database (maybe for the CDNs or something like that) and you need a larger connection limit.

SafetyNet Attestation fails Flutter Firebase Phone Authentication

I am working on one of my flutter project and trying to add firebase phone authentication but I encountered with the error related to safetynet.Whereas i am able to use other authentication methods e.g. SignInWithEmailAndPassword. Whenever I am calling my phoneLogin function i am getting the error. I have already installed google play service on my emulator.
CODE
Future phoneLogin(String phone) async {
BuildContext context;
try {
await auth.verifyPhoneNumber(
phoneNumber: '+91$phone',
timeout: const Duration(seconds: 30),
verificationCompleted: (PhoneAuthCredential credentials) async {
await auth.signInWithCredential(credentials);
},
verificationFailed: (FirebaseAuthException exception) {},
codeSent: (String verificationId, [int forcedResendingToken]) {
// print('1')
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => OtpPage(phone: phone),
),
);
},
codeAutoRetrievalTimeout: (String abc) {});
return null;
} catch (e) {
return null;
}
}
ERROR
E/zzbf ( 6483): SafetyNet Attestation fails basic integrity.
I/zzkn ( 6483): Provider GmsCore_OpenSSL not available
W/System ( 6483): Ignoring header X-Firebase-Locale because its value was null.
D/AndroidRuntime( 6483): Shutting down VM
E/AndroidRuntime( 6483): FATAL EXCEPTION: main
E/AndroidRuntime( 6483): Process: com.oneobit.greenobit, PID: 6483
E/AndroidRuntime( 6483): java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/browser/customtabs/CustomTabsIntent$Builder;
E/AndroidRuntime( 6483): at com.google.firebase.auth.internal.RecaptchaActivity.zza(com.google.firebase:firebase-auth##20.0.2:13)
E/AndroidRuntime( 6483): at com.google.android.gms.internal.firebase-auth-api.zztw.zzb(com.google.firebase:firebase-auth##20.0.2:7)
E/AndroidRuntime( 6483): at com.google.android.gms.internal.firebase-auth-api.zztw.onPostExecute(Unknown Source:2)
E/AndroidRuntime( 6483): at android.os.AsyncTask.finish(AsyncTask.java:771)
E/AndroidRuntime( 6483): at android.os.AsyncTask.access$900(AsyncTask.java:199)
E/AndroidRuntime( 6483): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
E/AndroidRuntime( 6483): at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime( 6483): at android.os.Looper.loop(Looper.java:223)
E/AndroidRuntime( 6483): at android.app.ActivityThread.main(ActivityThread.java:7656)
E/AndroidRuntime( 6483): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 6483): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
E/AndroidRuntime( 6483): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
E/AndroidRuntime( 6483): Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.browser.customtabs.CustomTabsIntent$Builder" on path: DexPathList[[zip file "/data/app/~~VMK8TkW9ozBJD9t7dnRn8g==/com.oneobit.greenobit-EtKxl5CBj6rDZiliq4I1ZQ==/base.apk"],nativeLibraryDirectories=[/data/app/~~VMK8TkW9ozBJD9t7dnRn8g==/com.oneobit.greenobit-EtKxl5CBj6rDZiliq4I1ZQ==/lib/x86, /data/app/~~VMK8TkW9ozBJD9t7dnRn8g==/com.oneobit.greenobit-EtKxl5CBj6rDZiliq4I1ZQ==/base.apk!/lib/x86, /system/lib, /system_ext/lib]]
E/AndroidRuntime( 6483): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207)
E/AndroidRuntime( 6483): at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
E/AndroidRuntime( 6483): at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
E/AndroidRuntime( 6483): ... 12 more
I/Process ( 6483): Sending signal. PID: 6483 SIG: 9
Lost connection to device.
I have already updated SHA256 key to my Firebase console.
Firebase have updated certain things one of them is they have included captcha verification before sending the code or OTP to mobile devices.
To solve this issue see bellow:
add the following to project/android/app/build.gradle
implementation "androidx.browser:browser:1.3.0"
add this in the dependencies section ...
dependencies {
implementation "androidx.browser:browser:1.3.0"
///
}
you can find the latest version here: android browser .
REASON:
The app tries to verify the captcha and send the code, for that it tries to launch a browser but because of the missing implementation it fails to load a browser and crashes the application.

Why does my opentok method does not work in firebase?

I use a firebase function which executes OpenTok SDK when it is triggered. The function creates a session. I was able to create a session successfully on my local server, but when I put it in production – in firebase- following error occurs:
Error creating session: Error: Failed to createSession. Error: The request failed: Error: getaddrinfo EAI_AGAIN api.opentok.com:443
at createSessionCallback (/srv/node_modules/opentok/lib/opentok.js:1125:16)
at Request._callback (/srv/node_modules/opentok/lib/client.js:59:14)
at self.callback (/srv/node_modules/request/request.js:185:22)
at emitOne (events.js:116:13)
at Request.emit (events.js:211:7)
at Request.onRequestError (/srv/node_modules/request/request.js:877:8)
at emitOne (events.js:121:20)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:401:9)
at emitOne (events.js:116:13)
Other methods of this third party SDK like token generation also works on firebase but the method createSession fails. Can you help me please?
exports.dbUpdate = functions.database.ref('/test/{pushId}/text').onUpdate((change, context) => {
const beforeData = change.before.val(); // data before the write
const afterData = change.after.val();
if (beforeData == afterData) {
console.log("Text did not change");
return null;
}
opentok = new OpenTok("...", "...");
var sessionId;
opentok.createSession({
mediaMode: "routed"
}, function(error, session) {
if (error) {
console.log("Error creating session:", error)
token = "Failed";
} else {
sessionId = session.sessionId;
token = opentok.generateToken(sessionId);
}
});
return change.after.ref.parent.child('neuertest').set(token);
});
//The same code works on local server
The free Spark plan only allows for HTTP calls to Google services (see Cloud Functions on https://firebase.google.com/pricing/)
You’ll need to upgrade your plan to be able to run your function

IllegalArgumentException: Unsupported value: null while login with twitter

I am trying to login with Twitter when i used dependency firebase_auth:^0.6.6 it was working perfactly and i fetch the user's Profile picture and the Code was
final TwitterLoginResult result = await twitterLogin.authorize();
switch (result.status)
{
case TwitterLoginStatus.loggedIn:
var session = result.session;
FirebaseUser user = await _auth.signInWithTwitter(
authToken: session.token, authTokenSecret: session.secret);
img=user.photoUrl;
}
but i migrated the app to AndroidX and this dependency was not compatible so i used firebase_auth: ^0.14.0+5 and this code was not working so i change the code to
final TwitterLoginResult result = await twitterLogin.authorize();
switch (result.status) {
case TwitterLoginStatus.loggedIn:
var session = result.session;
final AuthCredential credential =
TwitterAuthProvider.getCredential(authToken: session.token,
authTokenSecret: session.secret);
FirebaseUser user = (await _auth.signInWithCredential(credential)).user;
and this code is not working app is Crashing and showing the error
W/BiChannelGoogleApi(18829): [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzak#70a4ccf
W/InputMethodManager(18829): startInputReason = 1
D/FirebaseAuth(18829): Notifying id token listeners about user ( D71yiiEX7ubSon4xxcddKlSydn72 ).
D/FirebaseAuth(18829): Notifying auth state listeners about user ( D71yiiEXccccccccKlSydn72 ).
I/zygote64(18829): Do full code cache collection, code=124KB, data=91KB
I/zygote64(18829): After code cache collection, code=123KB, data=68KB
I/zygote64(18829): Do partial code cache collection, code=123KB, data=68KB
I/zygote64(18829): After code cache collection, code=123KB, data=68KB
I/zygote64(18829): Increasing code cache capacity to 512KB
D/AndroidRuntime(18829): Shutting down VM
E/AndroidRuntime(18829): FATAL EXCEPTION: main
E/AndroidRuntime(18829): Process: com.example.login_app, PID: 18829
E/AndroidRuntime(18829): java.lang.IllegalArgumentException: Unsupported value: null
E/AndroidRuntime(18829): at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:294)
E/AndroidRuntime(18829): at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:291)
E/AndroidRuntime(18829): at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:291)
E/AndroidRuntime(18829): at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:291)
E/AndroidRuntime(18829): at io.flutter.plugin.common.StandardMethodCodec.encodeSuccessEnvelope(StandardMethodCodec.java:57)
E/AndroidRuntime(18829): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:225)
E/AndroidRuntime(18829): at io.flutter.plugins.firebaseauth.FirebaseAuthPlugin$SignInCompleteListener.onComplete(FirebaseAuthPlugin.java:691)
E/AndroidRuntime(18829): at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
E/AndroidRuntime(18829): at android.os.Handler.handleCallback(Handler.java:808)
E/AndroidRuntime(18829): at android.os.Handler.dispatchMessage(Handler.java:101)
E/AndroidRuntime(18829): at android.os.Looper.loop(Looper.java:166)
E/AndroidRuntime(18829): at android.app.ActivityThread.main(ActivityThread.java:7529)
E/AndroidRuntime(18829): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(18829): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
E/AndroidRuntime(18829): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
I/Process (18829): Sending signal. PID: 18829 SIG: 9
Lost connection to device.
Please can someone explain to me how to resolve this problem?
Problem is with login task AND Androidx twitter_login_issue
Add this dependency in your pubspec.yaml file and let me know this working or not?
flutter_twitter_login:
git: git://github.com/eudangeld/flutter_twitter_login.git
Same issue (question) login_issue

Resources