2

I'm building a Flutter app that uses Firebase Auth and Firestore. Everything works fine on the Flutter side.

Now, I need to save battery info from iOS native Swift code (in AppDelegate.swift) so it can run in the background — which Flutter doesn't support directly.

To do this, I'm using a secondary FirebaseApp instance in Swift (named "flutter-app"), and I'm trying to write to Firestore using the existing user who was already authenticated in Flutter.

However, when I try to write to Firestore from Swift, I get this error:

[FirebaseFirestore][I-FST000001] WriteStream (313536646433373138) Stream error: 'Permission denied: Missing or insufficient permissions.'
[FirebaseFirestore][I-FST000001] Write at users/{uid}/devices/{deviceId} failed: Missing or insufficient permissions.

Even though:

  • auth.currentUser in Swift is not nil

  • The uid matches the one from the Flutter side

  • Firestore rules are correctly configured to allow users to write to their own documents

  • The same code path (writing to users/{uid}/devices/{deviceId}) works fine in Flutter

  • I initialized the secondary FirebaseApp using the same GoogleService-Info.plist as in Flutter.

  • I verified that FirebaseApp only initializes once and reuses the instance afterward.

  • I used Auth.auth(app: app) and checked that currentUser is valid.

  • I expected the write to Firestore to succeed, just like in Flutter, since the user is already logged in and Firestore rules allow it.

Here’s the relevant Swift code:

if FirebaseApp.app(name: "flutter-app") == nil {
    let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist")!
    let options = FirebaseOptions(contentsOfFile: path)!
    FirebaseApp.configure(name: "flutter-app", options: options)
}

let app = FirebaseApp.app(name: "flutter-app")!
let db = Firestore.firestore(app: app)
let auth = Auth.auth(app: app)

guard let currentUser = auth.currentUser else {
    print("User not logged in")
    return
}

// ... build docRef and call setData() ...

Here are the Firestore rules:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write, update: if request.auth != null && request.auth.uid == userId;

      match /devices/{deviceId} {
        allow read, write, update: if request.auth != null && request.auth.uid == userId;
      }
    }
  }
}

If there's anything I'm missing about how authentication works across native/Flutter with secondary FirebaseApp, I’d really appreciate any help or suggestions!

1 Answer 1

0

The issue was caused by Firebase dose not use the same instance in both flutter and swift, and Firestore being accessed from Swift before Flutter had finished initializing it.

Since Firestore locks its settings at first access, calling Firestore.firestore() too early in Swift (before Flutter finishes initialization) caused a fatal crash.

To fix it, I made sure Flutter fully initialized Firebase and triggered a dummy Firestore call before any Swift code touched Firestore. In main.dart, I added:

await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await FirebaseFirestore.instance.collection("initcheck").limit(1).get();

Since my Firestore rules required authentication, I also added:

match /initcheck/{docId} {
  allow read: if request.auth != null;
}

After that, saving data from Swift using the logged-in user worked perfectly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.