收到异常FAILED_PRECONDITION:查询需要索引

时间:2020-02-10 05:32:01

标签: android firebase google-cloud-firestore

我使用云数据库在Firebase中创建项目,并且我想将存储在文档中的empUID字段与当前UID进行比较。

我创建了一个查询,该查询在当前UIDempUID匹配但无法获取数据时获取数据。

请指导是我的查询权限,还是我需要更改代码

我的子收集路径

雇主(根集合)->职位发布(子集合)->求职者 详细信息(工作职位的子集合)

Logcat

2020-02-10 10:38:36.239 29836-29895/com.example.part_time_job I/Adreno: Build Config                     : S P 6.0.7 AArch64
2020-02-10 10:38:36.231 29836-29836/com.example.part_time_job W/RenderThread: type=1400 audit(0.0:9359): avc: denied { search } for name="proc" dev="debugfs" ino=16085 scontext=u:r:untrusted_app:s0:c183,c257,c512,c768 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0
2020-02-10 10:38:36.242 29836-29895/com.example.part_time_job I/Adreno: PFP: 0x016ee180, ME: 0x00000000
2020-02-10 10:38:36.231 29836-29836/com.example.part_time_job W/RenderThread: type=1400 audit(0.0:9360): avc: denied { search } for name="ctx" dev="debugfs" ino=16114 scontext=u:r:untrusted_app:s0:c183,c257,c512,c768 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0
2020-02-10 10:38:36.245 29836-29895/com.example.part_time_job I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
2020-02-10 10:38:36.245 29836-29895/com.example.part_time_job I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
2020-02-10 10:38:36.245 29836-29895/com.example.part_time_job D/libEGL: eglInitialize: exit(res=1)
2020-02-10 10:38:36.245 29836-29895/com.example.part_time_job I/OpenGLRenderer: Initialized EGL, version 1.4
2020-02-10 10:38:36.246 29836-29895/com.example.part_time_job D/OpenGLRenderer: Swap behavior 2
2020-02-10 10:38:36.241 29836-29836/com.example.part_time_job W/RenderThread: type=1400 audit(0.0:9361): avc: denied { search } for name="ctx" dev="debugfs" ino=16114 scontext=u:r:untrusted_app:s0:c183,c257,c512,c768 tcontext=u:object_r:qti_debugfs:s0 tclass=dir permissive=0
2020-02-10 10:38:36.369 29836-29894/com.example.part_time_job W/e.part_time_jo: Accessing hidden method Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V (light greylist, reflection)
2020-02-10 10:38:36.391 29836-29894/com.example.part_time_job W/e.part_time_jo: Accessing hidden method Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy; (light greylist, linking)
2020-02-10 10:38:36.391 29836-29894/com.example.part_time_job W/e.part_time_jo: Accessing hidden method Ldalvik/system/BlockGuard$Policy;->onNetwork()V (light greylist, linking)
2020-02-10 10:38:37.656 29836-29836/com.example.part_time_job E/RecyclerView: No adapter attached; skipping layout
2020-02-10 10:38:38.262 29836-29836/com.example.part_time_job E/Register4: Received an exception FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/part-time-job-74d92/firestore/indexes?create_composite=Cmxwcm9qZWN0cy9wYXJ0LXRpbWUtam9iLTc0ZDkyL2RhdGFiYXNlcy8oZGVmYXVsdCkvY29sbGVjdGlvbkdyb3Vwcy9Kb2IgQXBwbGljYW50IERldGFpbHMvaW5kZXhlcy9DSUNBZ09qWGg0RUsQAhoKCgZlbXBVSUQQARoKCgZ1c2VySWQQARoMCghfX25hbWVfXxAB
2020-02-10 10:38:38.263 29836-29877/com.example.part_time_job W/Firestore: (21.3.1) [Firestore]: Listen for Query(target=Query( collectionGroup=Job Applicant Details where userId == uOQXpA8WSgWb5DeDqXxLsdEz0G22 and empUID == null order by __name__);limitType=LIMIT_TO_FIRST) failed: Status{code=FAILED_PRECONDITION, description=The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/part-time-job-74d92/firestore/indexes?create_composite=Cmxwcm9qZWN0cy9wYXJ0LXRpbWUtam9iLTc0ZDkyL2RhdGFiYXNlcy8oZGVmYXVsdCkvY29sbGVjdGlvbkdyb3Vwcy9Kb2IgQXBwbGljYW50IERldGFpbHMvaW5kZXhlcy9DSUNBZ09qWGg0RUsQAhoKCgZlbXBVSUQQARoKCgZ1c2VySWQQARoMCghfX25hbWVfXxAB, cause=null}
2020-02-10 10:38:41.232 29836-29870/com.example.part_time_job V/FA: Inactivity, disconnecting from the service

我的Java代码

package com.example.part_time_job;


import android.location.Address;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;

import java.util.ArrayList;
import java.util.List;

import model.FInalApplyNotification;
import model.Jobpost;
import ui.JournalRecyclerAdapterNotificationEmp;
import util.JournalApi;


/**
 * A simple {@link Fragment} subclass.
 */
public class HistoryFragment extends Fragment {

    private static final String TAG = "Register4";


    private FirebaseUser user;
    private FirebaseAuth firebaseAuth;
    private FirebaseAuth.AuthStateListener authStateListener;
    private FirebaseFirestore db = FirebaseFirestore.getInstance();
    private List<FInalApplyNotification> journalList;
    private String empid;
    private String title;
    private String currentUserId;







    private RecyclerView recyclerViewnotifyemp;
    private JournalRecyclerAdapterNotificationEmp journalRecyclerAdapterNotificationEmp;


    private CollectionReference collectionReference=db.collection("Employer");
    private TextView no_listnotifyemp;




    public HistoryFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view=inflater.inflate(R.layout.fragment_history, container, false);
        firebaseAuth= FirebaseAuth.getInstance();
        user =firebaseAuth.getCurrentUser();

        no_listnotifyemp= view.findViewById(R.id.no_listnotifyemp);
        journalList=new ArrayList<>();

        recyclerViewnotifyemp=view.findViewById(R.id.recyclerViewnotifyemp);
        recyclerViewnotifyemp.setHasFixedSize(true);
        recyclerViewnotifyemp.setLayoutManager(new LinearLayoutManager(getActivity()));


        currentUserId=JournalApi.getInstance().getUserId();





        return view;
    }

    @Override
    public void onStart() {
        super.onStart();
        if (journalList!=null){
            journalList.clear();
        }

        FInalApplyNotification fInalApplyNotification=new FInalApplyNotification();
        fInalApplyNotification.setTitle(title);
        fInalApplyNotification.setUserId(currentUserId);

                db.collectionGroup("Job Applicant Details").whereEqualTo("userId",currentUserId).whereEqualTo("empUID",fInalApplyNotification.getEmpUID())
                    .get()
                    .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                        @Override
                        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
                            if (!queryDocumentSnapshots.isEmpty()) {
                                for (QueryDocumentSnapshot journals : queryDocumentSnapshots) {
                                    FInalApplyNotification fInalApplyNotification = journals.toObject(FInalApplyNotification.class);
                                    journalList.add(fInalApplyNotification);


                                }

                                journalRecyclerAdapterNotificationEmp = new JournalRecyclerAdapterNotificationEmp(getActivity(), journalList);
                                recyclerViewnotifyemp.setAdapter(journalRecyclerAdapterNotificationEmp);
                                journalRecyclerAdapterNotificationEmp.notifyDataSetChanged();


                            } else {

                                no_listnotifyemp.setVisibility(View.VISIBLE);

                            }
                        }
                    })
                    .addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            Log.e(TAG, "Received an exception " + e.getMessage() );


                        }
                    });



    }




}

我的查询

db.collectionGroup("Job Applicant Details").whereEqualTo("userId",currentUserId).whereEqualTo("empUID",fInalApplyNotification.getEmpUID())

2 个答案:

答案 0 :(得分:1)

作为例外情况,您必须为正在执行的查询创建索引。

FAILED_PRECONDITION:查询需要索引。您可以在这里创建它:{some link}

由异常提供的链接在输入到浏览器后将为Firebase控制台加载创建查询所需索引所需的所有详细信息。因此,您只需要访问链接并按照说明进行操作即可。

答案 1 :(得分:1)

Firebase Firestore主要有两种查询类型

  1. Simple queries
  2. Compound queries

  1. 简单查询只有条件,因此它们不需要数据库索引,例如
FirebaseFirestore.getInstance().collection("cities")
        .whereEqualTo("capital", true)
        .get()
        .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Log.d(TAG, document.getId() + " => " + document.getData());
                    }
                } else {
                    Log.d(TAG, "Error getting documents: ", task.getException());
                }
            }
        });
  1. 您的查询是复合查询,其中有多个其中个查询链接在一起,需要 composite index ,您可以在firebase console中创建复合索引,也可以使用error message创建复合索引,使用错误消息创建索引比较容易,它会打印在您的日志消息中,因为它可以处理字段和排序顺序并直接为您创建索引