Skip to content

"Firestore matchmaking + Agora token: Calls not connecting in Flutter app" #17716

@subintoms21

Description

@subintoms21

Is there an existing issue for this?

  • I have searched the existing issues.

Which plugins are affected?

Cloud Functions

Which platforms are affected?

Android

Description

Problem

I’m building a “Speak to Co-Learner” feature using Flutter + Firebase (Auth, Firestore, Functions) + Agora RTC.

Issue:

  • When two users press Start Call at the same time, matchmaking does not connect.
  • Firestore shows both users in call_requests with status=waiting.
  • Sometimes one gets status=matched, but Agora join fails because the token is empty or invalid.
  • Cloud Function for token generation runs, but occasionally returns empty.

Environment

  • Flutter: 3.19.6 (stable)
  • Dart: 3.3.3
  • Firebase packages:
    • firebase_auth: ^5.5.4
    • cloud_firestore: ^5.6.8
    • cloud_functions: ^5.0.4
  • Agora SDK: agora_rtc_engine ^6.x
  • Test device: Samsung Galaxy M33 (Android 14)

Firestore Rules (relevant part)

match /call_requests/{docId} {
  allow create, update, delete: if request.auth != null && request.auth.uid == docId;
  allow update: if request.auth != null && resource.data.partnerUid == request.auth.uid;
  allow read: if request.auth != null;
}
Code Samples (sanitized)

SpeakToCoLearnerScreen.dart

ElevatedButton(
  onPressed: _joinChannel,
  child: const Text('Start Call'),
);
MatchmakingScreen.dart (simplified)
static const String AGORA_APP_ID = 'YOUR_AGORA_APP_ID'; // replaced for safety

await _firestore.collection('call_requests').doc(uid).set({
  'uid': uid,
  'status': 'waiting',
  'createdAt': FieldValue.serverTimestamp(),
});

// Transaction to match partner
tx.update(otherRef, {
  'status': 'matched',
  'partnerUid': myUid,
  'channelId': channelId,
});

await _engine.joinChannel(
  token: token,
  channelId: channelId,
  uid: _rtcUid!,
  options: const ChannelMediaOptions(
    channelProfile: ChannelProfileType.channelProfileCommunication,
    clientRoleType: ClientRoleType.clientRoleBroadcaster,
  ),
);
Firebase Function (index.js)

exports.generateAgoraToken = onCall(
  { region: "us-central1", enforceAppCheck: true, secrets: ["AGORA_APP_ID", "AGORA_APP_CERT"] },
  (request) => {
    if (!request.auth) throw new HttpsError("unauthenticated", "Login required");

    const channelName = request.data.channelName;
    const uid = Number(request.data.uid || 0);
    const expireSeconds = Number(request.data.expireSeconds || 3600);

    const token = RtcTokenBuilder.buildTokenWithUid(
      process.env.AGORA_APP_ID,
      process.env.AGORA_APP_CERT,
      channelName,
      uid,
      RtcRole.PUBLISHER,
      Math.floor(Date.now() / 1000) + expireSeconds
    );

    return { token };
  }
);

Steps to Reproduce

User A logs in  taps Start Call.

User B logs in  taps Start Call within ~3 seconds.

Firestore shows both users in call_requests.

No successful match, or Agora join fails due to empty/invalid token.

Expected Result

Both users should be matched by Firestore transaction.

Firebase Function should return a valid Agora token.

Both users should join the same Agora channel and begin voice call.

Actual Result

Users remain waiting in Firestore.

Sometimes status updates to matched, but Agora join fails (Invalid Token or empty).

Notes

Verified with PowerShell: Agora token generation works fine using the same App ID/Cert.

The failure only happens when generating tokens via Firebase Callable Function in Flutter.

Likely issues could be:

Firestore transaction race condition

Cloud Function returning empty response intermittently

App Check occasionally blocking the request

Questions

Is my Firestore transaction logic correct for simultaneous matchmaking?

Why does my Firebase Function sometimes return an empty token?

Is there a recommended pattern for reliable matchmaking + Agora token handling with FlutterFire?


---





### Reproducing the issue

1. User A logs in  taps Start Call
2. User B logs in  taps Start Call within ~3 seconds
3. Firestore shows both users in call_requests
4. No successful match, or Agora join fails


### Firebase Core version

 3.15.2 

### Flutter Version

Put 3.19.6.

### Relevant Log Output

```shell
[MM] candidates=[abc123, xyz456]
⚠️ Agora error 103: Invalid Token
 Firebase issue: Token fetch failed (empty)
getting error while trying to connect coleaner aftrer loggin both phones=not matches found.cant find coleaner

Flutter dependencies

<Dart SDK 3.8.1
Flutter SDK 3.32.7
fluent_expert 1.0.8+10

dependencies:

  • agora_rtc_engine 6.5.2 [flutter flutter_web_plugins json_annotation ffi async meta iris_method_channel js]
  • change_app_package_name 1.5.0
  • cloud_firestore 5.6.12 [...]
  • cloud_functions 5.6.2 [...]
  • firebase_auth 5.7.0 [...]
  • firebase_core 3.15.2 [...]
  • firebase_messaging 15.2.10 [...]
  • flutter_tts 4.2.3 [...]
  • share_plus 11.0.0 [...]
  • speech_to_text 7.1.0 [...]
  • etc…

Additional context and comments

Note: I verified Agora token generation separately (using PowerShell and the same App ID/Cert) and it worked correctly. So the issue is not with Agora credentials. The failure only happens when generating the token through Firebase Cloud Functions in Flutter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    StaleIssue with no recent activityblocked: customer-responseWaiting for customer response, e.g. more information was requested.platform: androidIssues / PRs which are specifically for Android.plugin: functionstype: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions