Kotlin拒绝了Firebase Firestore许可

时间:2019-02-27 13:14:47

标签: android firebase kotlin google-cloud-firestore

我有一个Android Kotlin项目,我试图在Firebase Firestore中从一个名为“ environments”的集合(在根目录中)检索所有文档的列表。这对我来说是全新的,但我无法使它正常工作。到目前为止,在线研究未能给我正确的答案。

Firestore结构:

ROOT
- environments (is a collection)
  - fMzUHbiK7QMsyEdnLmmfksu0j5L2 (is a document)
    - name: "number1" (is a field)
  - rgeEwg7RhWgWaqlmhwg46dWSfowl (another document, etc.)
    - name: "number2"
- users
- etc.

安全规则:

(我确定第二部分(不安全)就足够了,但是我只是明确尝试过了)

service cloud.firestore {
  match /databases/{database}/documents {

    match /environments/{document=**} {
      allow read, write: if true;
    }

    match /{document=**} {
      allow read, write: if true;
    }
  }
}

我已经使用Firebase助手将我的应用程序链接到firebase。还尝试了手动方法。所以我有这个:

根级build.gradle

buildscript {
    // ...
    dependencies {
        // ...
        classpath 'com.google.gms:google-services:4.2.0' // google-services plugin
    }
}

allprojects {
    // ...
    repositories {
        google() // Google's Maven repository
        // ...
    }
}

app/build.gradle

apply plugin: 'com.android.application'

android {
  // ...
}

dependencies{
  // ..
  implementation 'com.google.firebase:firebase-core:16.0.7'
  implementation 'com.google.firebase:firebase-firestore:18.0.1'
}

apply plugin: 'com.google.gms.google-services'

我将google-services.json文件与文档中提到的根级别build.gradle放在同一目录中。

我创建了一个带有1个按钮的Kotlin项目(仅用于控制功能何时触发,此功能触发将在以后自动执行)。 请注意,我不对任何用户进行身份验证,我试图为所有人创建一个愉快的流程,稍后再进行身份验证和安全性。

科特林

现在以下代码主要来自官方文档

lateinit var db: FirebaseFirestore

override fun onCreate(savedInstanceState: Bundle?) {
  // ...
  db = FirebaseFirestore.getInstance()

  button.setOnClickListener {
  db.collection("environments")
   .get()
     .addOnSuccessListener { result ->
       for (document in result) {
         Log.d("success", document.id + " => " + document.data)
       }
     }
     .addOnFailureListener { exception ->
         Log.d("fail", "Error getting documents: ", exception)
       }
     }
   }
}

调试/日志

I/Firestore: (0.6.6-dev) [FirestoreClient]: Initializing. user=null
I/Firestore: (0.6.6-dev) [Persistence]: Starting transaction: Start MutationQueue
I/Firestore: (0.6.6-dev) [Persistence]: Starting transaction: Allocate query
W/eldingenish_cw: Accessing hidden field Ljava/nio/Buffer;->address:J (light greylist, reflection)
I/Firestore: (0.6.6-dev) [WatchStream]: (e57e2f1) Stream sending: # com.google.firestore.v1.ListenRequest@d97c49a6
    add_target {
      query {
        parent: "projects/[projectname-hidden]/databases/(default)/documents"
        structured_query {
          from {
            collection_id: "environments"
          }
          order_by {
            direction: ASCENDING
            direction_value: 1
            field {
              field_path: "__name__"
            }
          }
        }
      }
      target_id: 2
    }
    database: "projects/[projectname-hidden]/databases/(default)"

I/Firestore: (0.6.6-dev) [FirestoreCallCredentials]: Successfully fetched token.
I/Firestore: (0.6.6-dev) [WatchStream]: (e57e2f1) Stream is ready
I/Firestore: (0.6.6-dev) [WatchStream]: (e57e2f1) Stream received headers: {date=Wed, 27 Feb 2019 12:34:34 GMT}
I/Firestore: (0.6.6-dev) [WatchStream]: (e57e2f1) Stream received: # com.google.firestore.v1.ListenResponse@72b77077
    target_change {
      target_change_type: ADD
      target_change_type_value: 1
      target_ids: 2
    }
I/Firestore: (0.6.6-dev) [WatchStream]: (e57e2f1) Stream received: # com.google.firestore.v1.ListenResponse@d3efdcbe
    target_change {
      cause {
        code: 7
        message: "Missing or insufficient permissions."
      }
      target_change_type: REMOVE
      target_change_type_value: 2
      target_ids: 2
    }
I/Firestore: (0.6.6-dev) [Persistence]: Starting transaction: Release query
W/Firestore: (0.6.6-dev) [Firestore]: Listen for Query(environments) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}

D/fail: Error getting documents:
com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.

Caused by: io.grpc.StatusException: PERMISSION_DENIED: Missing or insufficient permissions.

实验

我开始认为自己的代码有错误,所以我做了一些尝试。

替代

.addSnapshotListener { querySnapshot, firebaseFirestoreException ->
  if(firebaseFirestoreException != null) {
    Log.d("main", "Error ggetting documents")
    return@addSnapshotListener
  }

  querySnapshot?.documents?.forEach {document ->
    Log.d("main", document.id + " => " + document.data)
  }
}

添加文档

val item = HashMap<String, Any>()
item["name"] = "test"
db.collection("environments")
  .add(item)
    .addOnSuccessListener { documentReference ->
      Log.d("main", "DocumentSnapshot written with ID: " + 
      documentReference.id)
    }
    .addOnFailureListener { e ->
      Log.w("main", "Error adding document", e)
    }

虽然我的安全规则不错,但似乎没有任何许可? (我无法在模拟器中测试get集合,它仅适用于文档路径)我可以看到该应用程序已链接到控制台中的项目。另外,firestore读取的使用也在增加。

有人可以帮助我吗?

请注意,我在Zscaler防火墙后面。我已将证书导入Android Studio。我的模拟器可以访问互联网,但是所有SSL证书都被评估为无效。我还尝试在具有4G互联网连接(没有Zscaler)的实际手机上运行该应用程序。

1 个答案:

答案 0 :(得分:1)

我在创建项目时删除了Google服务帐户(在云平台中)。试图从头开始,原来SDK使用了这些服务帐户。

解决方案::请勿删除自动生成的服务帐户!

请注意,可以手动添加这些服务帐户,但是您不能选择它们在创建项目时获得的角色,必须让它们成为所有者或通过反复试验选择特定的权限来找出它们的需求。

另一种替代查询方式

.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        for (document in task.result!!) {
            Log.d("1", document.id + " => " + document.data)
        }
    } else {
        Log.w("1", "Error getting documents.", task.exception)
    }
}

原始帖子中的代码现在也可以使用! (而且更整洁的imo)