DatabaseReference setValue 像在循环中一样工作

Posted

技术标签:

【中文标题】DatabaseReference setValue 像在循环中一样工作【英文标题】:DatabaseReference setValue woks like in a loop 【发布时间】:2021-06-10 00:31:01 【问题描述】:

我尝试在我的 Firebase 实时数据库中设置一个布尔值,但是当我在 addValueListener 函数中运行 set Value 时,它​​开始永远更改值,并且似乎 onCreateView 在循环中开始。 这是我的代码:

private static DatabaseReference myref;

    public static home_fragment newInstance(String param1, String param2) 
        home_fragment fragment = new home_fragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        if (getArguments() != null) 
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        this.container = container;
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        myref = FirebaseDatabase.getInstance("https://piazzodivale-default-rtdb.europe-west1.firebasedatabase.app").getReference("Users");
         nome = "";
         getNome(); 
        present_button = view.findViewById(R.id.presenza);
        present_button.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                myref.child(userID).addValueEventListener(new ValueEventListener() 
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) 
                        if (snapshot.child("presente").getValue(Boolean.class) == true)
                            myref.child(userID).child("presente").setValue(false);

                         else 
                            myref.child(userID).child("presente").setValue(true);
                        
                    

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) 

                    
                );


            
        );



        return view;

    
    @Override
    public void onStart() 
        super.onStart();
        Log.d("Presente", String.valueOf(presente));

    
private void getNome() //ottine il nome dell'utente attraverso il db e lo salva nella variabile nome
        userMap.clear();

        myref.child(userID).addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) 

                userMap.put("Nome",  snapshot.child("Nome").getValue(String.class));
                Log.d("Nome", userMap.get("Nome").toString());
            

            @Override
            public void onCancelled(@NonNull DatabaseError error) 

            
        );


    


我想要在单击按钮时控制我的数据库中的布尔值,如果它为真,则将其设置为假,如果为假,则将其设置为真。当我单击按钮时,值会从 false 变为 true,从 true 变为 false,并且永远不会停止。

2021-03-12 00:53:18.504 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:18.505 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.501 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 638 lines
2021-03-12 00:53:19.502 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.505 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.898 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 269 lines
2021-03-12 00:53:19.899 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:19.900 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:20.505 19301-19301/com.example.stanzetta I/chatty: uid=10165(com.example.stanzetta) identical 365 lines
2021-03-12 00:53:20.507 19301-19301/com.example.stanzetta D/Nome: Valerio
2021-03-12 00:53:20.509 19301-19301/com.example.stanzetta D/Nome: Valerio

【问题讨论】:

【参考方案1】:

这是因为您正在侦听对 /Users/$uid 的更改,然后在其中写入更改。

最简单的解决方案是使用单值事件监听器:

myref.child(userID).addListenerForValueEvent(new ValueEventListener() 
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) 
        if (snapshot.child("presente").getValue(Boolean.class) == true)
            myref.child(userID).child("presente").setValue(false);

         else 
            myref.child(userID).child("presente").setValue(true);
        
    

    @Override
    public void onCancelled(@NonNull DatabaseError error) 
       throw error.toException(); // never ignore errors
    
);

【讨论】:

以上是关于DatabaseReference setValue 像在循环中一样工作的主要内容,如果未能解决你的问题,请参考以下文章

Swift 上的 Firebase IOS:使用未声明的类型“DatabaseReference”

DatabaseReference和FirebaseDatabase - 无法解析符号

如何将增量发票编号放入 DatabaseReference

Firebase 实时数据库 - DatabaseReference.push().getKey() 是一个时间戳

Firebase DatabaseReference 按指定值过滤

如果数据没有插入到firebase中,我怎么能发出错误消息(这是我的代码)