android FirebaseFirestoreException:PERMISSION_DENIED:缺少权限或权限不足

qvsjd97n  于 2023-06-20  发布在  Android
关注(0)|答案(4)|浏览(194)

我有一个问题,我们的应用程序能够从firebase firestore读取。我们有一个应用程序与2变化释放和调试。它运行得很好,我没有改变任何东西。
生产/发布工作正常。
我正在开发一个单独的应用程序,它使用相同的FireStore,而且这个应用程序也运行得很好(尚未发布)。
我在谷歌上搜索了这个问题,其中大部分都把我带到了SO,但几乎所有的答案都是将安全规则更改为:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

这很不安全我们的规则设置为:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
            allow read;
            allow write: if request.auth != null;
    }
  }
}

FBAuthUI.kt

class FBAuthUI : AppCompatActivity() {

    private val COLLECTION_PATH_USERS = "Users"
    private val RC_SIGN_IN: Int = 100
    private val RC_SIGN_UP: Int = 200
    private val TAG = "AuthUiActivity"

    private val TOS_URL = ""
    private val PRIVACY_POLICY_URL = ""

    // Choose authentication providers
    private val providers = arrayListOf(
            AuthUI.IdpConfig.EmailBuilder().build(),
            AuthUI.IdpConfig.GoogleBuilder().build(),
            AuthUI.IdpConfig.FacebookBuilder().build())

    private var userRef: CollectionReference? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Create and launch sign-in intent
        startActivityForResult(
                AuthUI.getInstance()
                        .createSignInIntentBuilder()
                        .setAvailableProviders(providers)
                        .setLogo(R.drawable.logo_red)
                        .setTheme(R.style.SignInTheme)
                        .setTosAndPrivacyPolicyUrls(
                                TOS_URL,
                                PRIVACY_POLICY_URL)
                        .build(),
                RC_SIGN_IN)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.i(TAG, requestCode.toString())
        if (requestCode == RC_SIGN_IN) {
            val idpResponse = IdpResponse.fromResultIntent(data)
            if (resultCode == Activity.RESULT_OK) {
                try {
                    if (idpResponse?.isNewUser() == true) {
            //signup code
            …
                    } else {
                        startActivity(Intent(this, MainActivity::class.java))
                    }
                } catch (e: JSONException) {
                    e.printStackTrace()
                }
            }else {
                // Sign in failed. If response is null the user canceled the
                // sign-in flow using the back button. Otherwise check
                // response.getError().getErrorCode() and handle the error.
                if (idpResponse != null) {
                    Log.d(TAG, idpResponse.error?.errorCode.toString())
                    Toast.makeText(this, "Unable to sign in. Please try again later", Toast.LENGTH_LONG).show()
                } else {
                    startActivity(Intent(this, LandingPageActivity::class.java))
                }
            }
        }
}

MainActivity.kt

class MainActivity : AppCompatActivity(),{
…

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val homeFrag: Fragment = Home()
        val searchFrag: Fragment = SearchFragment()
        val profileFrag: Fragment = ProfileFragment()
        val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_navigation)

        bottomNav.setOnNavigationItemSelectedListener { item ->
            when (item.itemId) {
                R.id.home_nav -> {
                        commitFragment(homeFrag)
                }
                R.id.nav_search -> {
                    commitFragment(searchFrag)
                }
                R.id.profile_nav -> {
                        commitFragment(profileFrag)
                }
                else -> {
                        commitFragment(homeFrag)
                }
            }
            true
        }

        if (savedInstanceState == null) {
            bottomNav.selectedItemId = R.id.home_nav
        }

        setSupportActionBar(toolbar)
        supportActionBar!!.setDisplayShowTitleEnabled(false)
    }

    private fun commitFragment(fragment: Fragment) {
        val fm = supportFragmentManager
        val fragTransition = fm.beginTransaction().addToBackStack(fragment.toString())
        fragTransition.replace(R.id.container, fragment).commit()
    }

    companion object {
        var bottomNav: BottomNavigationView? = null
        var CONTEXT: Context? = null
        private val TAG = MainActivity::class.java.simpleName
    }
}

SearchFragment.java

public class SearchFragment extends Fragment {
    private static final String COLLECTION_PATH_VENDORS = “BookStores”;

    private SearchAdapter searchAdapter;
    private ArrayList<BookStore> bookstores;
    private String searchString;
    private ImageView searchImage;
    private EditText searchET;
    Boolean clickedCategories;
    ArrayList<BookStore> bkstore = new  ArrayList<>();
    ArrayList<String> list = new  ArrayList<>();

    private RecyclerView recyclerView;
    private DatabaseReference dbRef;
    private CollectionReference bookStoreRef;
    private String category;

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //Initialize view
        View fragmentView = inflater.inflate(R.layout.fragment_search, container, false);

        recyclerView = fragmentView.findViewById(R.id.sr_recycler);
        recyclerView.hasFixedSize();
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(),
                DividerItemDecoration.VERTICAL));

        // Obtain Cloud Firestore instance
        FirebaseFirestore db = FirebaseFirestore.getInstance();
        bookStoreRef = db.collection(COLLECTION_PATH_VENDORS);

        searchET = getActivity().findViewById(R.id.search_box);
        searchET.setCursorVisible(true);
        displayAll();

        SearchAdapter searchAdapter = new SearchAdapter(getContext(), bkstore);
        recyclerView.setAdapter(searchAdapter);

        return fragmentView;

    }

    private void displayAll() {
        Log.d("UserID Tag ", FirebaseAuth.getInstance().getCurrentUser().getUid());
        bookStoreRef.get().addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot document : task.getResult()) {

                    final BookStore aBookStore = new Bookstore();

                    aBookStore.setName(document.getString("Name"));
                   aBookStore.setCategory(document.getString("Category"));
                   aBookStore.setDescription(document.getString("Description"));
                   aBookStorek.setImage(document.getString("Image"));
                    aBookStore.setID(document.getId());

                    bkstore.add(DisplayResults(document));
                    recyclerView.removeAllViews();
                }
            } else {
                Log.w(TAG, "Error getting documents.", task.getException());
            }
        });
    }

    private BookStore DisplayResults(QueryDocumentSnapshot document){
        BookStore aBookStore = new BookStore();

        aBookStore.setName(document.getString("Name"));
                   aBookStore.setCategory(document.getString("Category"));
                   aBookStore.setDescription(document.getString("Description"));
                   aBookStorek.setImage(document.getString("Image"));
                    aBookStore.setID(document.getId());

        return aBookStore.;
    }

}

日志返回:

D/UserID Tag: E4ARmAfe7aVG8oRiizHqWJatZlY2
W/Firestore: (24.0.0) [Firestore]: Listen for Query(target=Query(BookStores order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
W/ContentValues: Error getting documents.
    com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.
        at com.google.firebase.firestore.util.Util.exceptionFromStatus(Util.java:117)
        at com.google.firebase.firestore.core.EventManager.onError(EventManager.java:166)
        at com.google.firebase.firestore.core.SyncEngine.removeAndCleanupTarget(SyncEngine.java:588)
        at com.google.firebase.firestore.core.SyncEngine.handleRejectedListen(SyncEngine.java:424)
        at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleRejectedListen(MemoryComponentProvider.java:104)
        at com.google.firebase.firestore.remote.RemoteStore.processTargetError(RemoteStore.java:577)
        at com.google.firebase.firestore.remote.RemoteStore.handleWatchChange(RemoteStore.java:461)
        at com.google.firebase.firestore.remote.RemoteStore.access$100(RemoteStore.java:53)
        at com.google.firebase.firestore.remote.RemoteStore$1.onWatchChange(RemoteStore.java:176)
        at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:109)
        at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:38)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onNext$1$com-google-firebase-firestore-remote-AbstractStream$StreamObserver(AbstractStream.java:119)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$ExternalSyntheticLambda3.run(Unknown Source:4)
        at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67)
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onNext(AbstractStream.java:110)
        at com.google.firebase.firestore.remote.FirestoreChannel$1.onMessage(FirestoreChannel.java:131)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:656)
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:641)
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:234)
        at java.lang.Thread.run(Thread.java:923)
     Caused by: io.grpc.StatusException: PERMISSION_DENIED: Missing or insufficient permissions.
        at io.grpc.Status.asException(Status.java:543)
        at com.google.firebase.firestore.util.Util.exceptionFromStatus(Util.java:115)
        at com.google.firebase.firestore.core.EventManager.onError(EventManager.java:166) 
        at com.google.firebase.firestore.core.SyncEngine.removeAndCleanupTarget(SyncEngine.java:588) 
        at com.google.firebase.firestore.core.SyncEngine.handleRejectedListen(SyncEngine.java:424) 
        at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleRejectedListen(MemoryComponentProvider.java:104) 
        at com.google.firebase.firestore.remote.RemoteStore.processTargetError(RemoteStore.java:577) 
        at com.google.firebase.firestore.remote.RemoteStore.handleWatchChange(RemoteStore.java:461) 
        at com.google.firebase.firestore.remote.RemoteStore.access$100(RemoteStore.java:53) 
        at com.google.firebase.firestore.remote.RemoteStore$1.onWatchChange(RemoteStore.java:176) 
        at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:109) 
        at com.google.firebase.firestore.remote.WatchStream.onNext(WatchStream.java:38) 
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onNext$1$com-google-firebase-firestore-remote-AbstractStream$StreamObserver(AbstractStream.java:119) 
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$ExternalSyntheticLambda3.run(Unknown Source:4) 
        at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67) 
        at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onNext(AbstractStream.java:110) 
        at com.google.firebase.firestore.remote.FirestoreChannel$1.onMessage(FirestoreChannel.java:131) 
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInternal(ClientCallImpl.java:656) 
        at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1MessagesAvailable.runInContext(ClientCallImpl.java:641) 
        at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37) 
        at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:133) 
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:234) 
        at java.lang.Thread.run(Thread.java:923) 
V/FA: Inactivity, disconnecting from the service
W/Firestore: (24.0.0) [WatchStream]: (9a4fb5d) Stream closed with status: Status{code=CANCELLED, description=Disconnecting idle stream. Timed out waiting for new targets., cause=null}.

我不知道这是什么问题。我甚至尝试更改安全规则,但仍然得到缺少权限的错误。
有人有其他建议吗?

jjjwad0x

jjjwad0x1#

Firestore安全规则

1.打开Firebase控制台,然后单击项目。
1.单击屏幕左侧的Firestore。
1.在Firestore页面上,单击规则选项卡。
1.用以下规则取代现有规则:

rules_version = '2';
service cloud.firestore {
 match /databases/{database}/documents { 
  match /customers/{customerID} {
  allow read:
   if request.auth.uid != null
     && request.auth.token.firebase.sign_in_provider == "google.com"
     && request.auth.token.email == customerID
    }
  }
}

此规则赠款customers集合的只读权限。该规则验证您是否已通过在Identity Platform中配置的Google登录提供程序登录。它还确保您只能检索具有与您的电子邮件地址匹配的客户ID的文档。

注意:无论是检索单个文档还是执行查询,对Firestore的请求始终按照数据库安全规则进行评估。

1.单击“发布”。

t1qtbnec

t1qtbnec2#

这里有两个单独的子句:

allow read;
allow write: if request.auth != null;

对于write,您要求用户进行身份验证,但对于阅读,您没有指定任何条件,这显然意味着不允许读取。
我的猜测是,您希望if子句应用于读取和写入,您可以使用:

allow read, write: if request.auth != null;
44u64gxh

44u64gxh3#

我不确定根本问题是什么,但在删除google-services.json并重新下载后,问题似乎得到了解决。

y4ekin9u

y4ekin9u4#

我很久以前就面临这个问题了!却没有任何解决办法!我已经尝试了所有的可能性,正在提到的互联网SOF,谷歌社区和Android社区!我已经尝试更改数据库规则,并再次注册应用程序,甚至从Firebase下载新的google-services.json。但是没有什么对我有用!不,我没有路可走!如果有人知道,请告诉我解决办法。

相关问题