【问题标题】:Android: Firestore fails with "Found conflicting setters with name: setWallpaper"Android:Firestore 失败并显示“发现名称冲突的设置器:setWallpaper”
【发布时间】:2019-02-03 08:07:33
【问题描述】:

不要仅仅根据标题就快速判断,我知道以前有人问过类似的问题,但这个问题有点不同。请耐心看完。

所以我定义了一个BaseUser 类如下:

import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.Exclude;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.storage.FirebaseStorage;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class BaseUser
{
    private static final String TAG = "BaseUser";

    /**
     * Firebase Authentication and Database
     */
    protected FirebaseAuth auth;
    protected FirebaseFirestore db;
    protected FirebaseStorage st;

    /**
     * General BaseUser Info
     */
    private String firstName;
    private String lastName;
    private List<String> phones;
    private List<String> emails;
    private List<AddressLocation> addresses;

    public BaseUser()
    {
        auth = FirebaseAuth.getInstance();
        db = FirebaseFirestore.getInstance();
        st = FirebaseStorage.getInstance();
        phones = new ArrayList<>();
        emails = new ArrayList<>();
        addresses = new ArrayList<>();
    }

    /**
     * Getters
     */

    public final String getFirstName()
    {
        return firstName;
    }

    public final String getLastName()
    {
        return lastName;
    }

    @Exclude
    public final List<String> getPhones()
    {
        return phones;
    }

    @Exclude
    public final List<String> getEmails()
    {
        return emails;
    }

    @Exclude
    public final List<AddressLocation> getAddresses()
    {
        return addresses;
    }

    /**
     * Special Getters
     */

    @Exclude
    public final String getPhone(int index)
    {
        return phones.get(index);
    }

    // SimilarStuff


    /**
     * Setters
     */

    @Exclude
    public final void setFirstName(String firstName)
    {
        this.firstName = firstName;
    }

    @Exclude
    public final void setLastName(String lastName)
    {
        this.lastName = lastName;
    }

    @Exclude
    public final void setPhones(List<String> phones)
    {
        this.phones = phones;
    }

    @Exclude
    public final void setEmails(List<String> emails)
    {
        this.emails = emails;
    }

    @Exclude
    public final void setAddresses(List<AddressLocation> addresses)
    {
        this.addresses = addresses;
    }

    /**
     * Special Setters
     */

    @Exclude
    public final void addPhone(String phone)
    {
        this.phones.add(phone);
    }

    // SimilarStuff

    /**
     * Authentication
     */
    @Exclude
    public final boolean isLoggedIn()
    {
        assert(auth != null);
        return (auth.getCurrentUser() != null);
    }

    /**
     * Shared BaseUser Instance
     */

    protected static BaseUser holder = new BaseUser();

    @Exclude
    public static BaseUser getInstance()
    {
        assert(holder != null);
        return holder;
    }

    /**
     * Database
     */

    @Exclude
    protected final void downloadUser(final Callable<Void> callback)
    {
        // Doesn't get called for now.
    }

    @Exclude
    protected final void uploadUser()
    {
        assert(isLoggedIn());
        db.collection("users").document(auth.getCurrentUser().getUid()).set(this).addOnFailureListener(new OnFailureListener()
        {
            @Override
            public void onFailure(@NonNull Exception e)
            {
                Log.wtf(TAG, "Failed to write user data");
            }
        });
    }
}

如您所见,该类定义了几个字符串和几个数组。并且绝对不包括可能有setWallpaper 的任何其他内容。此外,如您所见,为了找到错误的来源,我实际上排除了所有函数(是的,即使它们不是以 setget 开头),除了读取两个简单的字符串。

现在当uploadUser 方法被调用时,我得到以下错误:

java.lang.RuntimeException: Found conflicting setters with name: setWallpaper (conflicts with setWallpaper defined on android.content.ContextWrapper)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.<init>(com.google.firebase:firebase-firestore@@18.0.0:632)
        at com.google.firebase.firestore.util.CustomClassMapper.loadOrCreateBeanMapperForClass(com.google.firebase:firebase-firestore@@18.0.0:348)
        at com.google.firebase.firestore.util.CustomClassMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:169)
        at com.google.firebase.firestore.util.CustomClassMapper.access$300(com.google.firebase:firebase-firestore@@18.0.0:53)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:774)
        at com.google.firebase.firestore.util.CustomClassMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:170)
        at com.google.firebase.firestore.util.CustomClassMapper.access$300(com.google.firebase:firebase-firestore@@18.0.0:53)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:774)
        at com.google.firebase.firestore.util.CustomClassMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:170)
        at com.google.firebase.firestore.util.CustomClassMapper.access$300(com.google.firebase:firebase-firestore@@18.0.0:53)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:774)
        at com.google.firebase.firestore.util.CustomClassMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:170)
        at com.google.firebase.firestore.util.CustomClassMapper.serialize(com.google.firebase:firebase-firestore@@18.0.0:101)
        at com.google.firebase.firestore.util.CustomClassMapper.convertToPlainJavaTypes(com.google.firebase:firebase-firestore@@18.0.0:77)
        at com.google.firebase.firestore.UserDataConverter.convertAndParseDocumentData(com.google.firebase:firebase-firestore@@18.0.0:216)
        at com.google.firebase.firestore.UserDataConverter.parseSetData(com.google.firebase:firebase-firestore@@18.0.0:75)
        at com.google.firebase.firestore.DocumentReference.set(com.google.firebase:firebase-firestore@@18.0.0:174)
        at com.google.firebase.firestore.DocumentReference.set(com.google.firebase:firebase-firestore@@18.0.0:153)
        at com.companyname.projectname.authentication.SignupActivity$6$1$1.onComplete(SignupActivity.java:297)
        at com.google.android.gms.tasks.zzj.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6718)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

我搜索了我的文件夹以找出包含 setWallpaper 的内容,我发现了以下内容:

shell$ grep -rnw "setWallpaper" .
Binary file ./authentication/build/intermediates/transforms/instantRun/AppName/debug/0/com/companyname/projectname/authentication/ResetPasswordActivity.class matches
Binary file ./authentication/build/intermediates/transforms/instantRun/AppName/debug/0/com/companyname/projectname/authentication/WelcomeActivity.class matches
Binary file ./authentication/build/intermediates/transforms/instantRun/AppName/debug/0/com/companyname/projectname/authentication/SignupActivity.class matches
Binary file ./authentication/build/intermediates/transforms/instantRun/AppName/debug/0/com/companyname/projectname/authentication/LoginActivity.class matches
Binary file ./authentication/build/intermediates/transforms/instantRun/AppName/debug/0/com/companyname/projectname/authentication/PhoneVerificationActivity.class matches
Binary file ./authentication/build/intermediates/transforms/dexBuilder/AppName/debug/265/com/companyname/projectname/authentication/LoginActivity.dex matches
Binary file ./authentication/build/intermediates/transforms/dexBuilder/AppName/debug/265/com/companyname/projectname/authentication/WelcomeActivity.dex matches
Binary file ./authentication/build/intermediates/transforms/dexBuilder/AppName/debug/265/com/companyname/projectname/authentication/PhoneVerificationActivity.dex matches
Binary file ./authentication/build/intermediates/transforms/dexBuilder/AppName/debug/265/com/companyname/projectname/authentication/ResetPasswordActivity.dex matches
Binary file ./authentication/build/intermediates/transforms/dexBuilder/AppName/debug/265/com/companyname/projectname/authentication/SignupActivity.dex matches
Binary file ./authentication/build/intermediates/transforms/dexMerger/AppName/debug/1/classes.dex matches

所以BaseUsersetWallpaper 这件事完全无关。它只与我的 UI 活动有关(而且我也没有明确使用它)。

我尝试过的:

  1. 排除除简单字符串的 2 个设置器之外的所有内容,如上所述。
  2. 我想也许让BaseUser 类本身处理 Firestore 会导致问题,所以我尝试在课堂外做同样的事情。一样。
  3. 我尝试使用 Firebase 数据库而不是 Firestore。一样。
  4. 还有其他类继承BaseUser。我已经禁用了所有这些。相同的。 (我什至不确定为什么会出现问题!)

额外信息

我不确定以下内容是否相关,但考虑到错误的奇怪性质,我还是要把它扔在这里。

BaseUser 类位于名为user 的单独模块中。处理身份验证的 UI 类(并在上面的 grep 输出中列出)位于名为 authentication 的单独模块中。第三个模块core 定义了firebase 库依赖项和来自google-services.json 的必要信息。

我还必须提到,通过这种模块配置,我可以很好地使用 Firebase 身份验证。只有 Firestore 或 Firebase 数据库有问题。

问题

现在 Firestore 到底为什么会抱怨我班上没有的二传手?我该如何解决这个问题?

编辑 1

我现在尝试了两种不同的方法:

我尝试上传一个简单的地图,所以在uploadUser 函数中我添加了以下内容:

protected final void uploadUser()
{
    assert(isLoggedIn());
    Map<String, Object> city = new HashMap<>();
    city.put("name", "Los Angeles");
    city.put("state", "CA");
    city.put("country", "USA");
    db.collection("users").document(auth.getCurrentUser().getUid()).set(city);
}

效果很好,然后我尝试添加一个简单的类作为要上传的对象。如下:

protected final void uploadUser()
{
    class Stupid {
        public String name;
        public String email;

        public Stupid()
        {
        }

        public Stupid(String name, String email)
        {
            this.name = name;
            this.email = email;
        }

        public String getName()
        {
            return name;
        }

        public void setName(String name)
        {
            this.name = name;
        }

        public String getEmail()
        {
            return email;
        }

        public void setEmail(String email)
        {
            this.email = email;
        }
    }
    Stupid stupid = new Stupid("Name", "Email");
    db.collection("users").document(auth.getCurrentUser().getUid()).set(stupid);
}

这又给了我与setWallpaper 相同的错误。我还尝试了另一种 Stupid 类的变体,它使用整数而不是字符串。也一样。一个愚蠢的简单 POJO 类。这整件事有什么问题?!我以前一直在 Firebase 数据库中使用类和对象。在这种情况下我缺少什么?

【问题讨论】:

  • 您是否尝试过简单地将方法名称更改为其他名称?你也遇到同样的错误吗?
  • 如果您的意思是uploadUser 函数,那么是的,尝试过。没有效果。
  • 问题是,我在以前的项目中有一个几乎相同的类,我一直将它与 Firebase 数据库一起使用,而我从来不需要处理任何这些愚蠢的东西。它还有具有相同命名约定的私有成员、公共 setter 和 getter 等。所以我真的不明白在这种情况下有什么遗漏或错误。
  • 您是否尝试将值直接设置到公共字段中?
  • 在 Edit 1 部分的 Stupid 类中尝试过。成员变量是公共的还是私有的,getter 和 setter 并没有改变任何东西。我还尝试在上传成员变量之前自行打印它们,以确保它们按预期正常,而且它们确实如此。

标签: android firebase google-cloud-firestore


【解决方案1】:

好的,所以我做了两件事,不确定哪一个修复了它(也许两者都解决了?!)

之前,我正在检查 Google Play 服务的可用性。所以,为此,我包括了com.google.android.gms:play-services-base:16.1.0。这导致我收到错误Error: Cannot fit requested classes in a single dex file. Try supplying a main-dex list. # methods: 72477 &gt; 65536。我的解决方案是添加multiDexEnable 'true'。我现在所做的是关注this answer。所以我删除了所有多 dex 的东西,改用com.google.android.gms:play-services-gcm:16.0.0

我做的第二件事是禁用即时运行。

现在,我拥有的相同代码就像一个魅力,并且能够在 Firestore 中读/写。

我对发生的事情没有任何解释。但是现在问题已经解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-27
    相关资源
    最近更新 更多