【发布时间】: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 的任何其他内容。此外,如您所见,为了找到错误的来源,我实际上排除了所有函数(是的,即使它们不是以 set 或 get 开头),除了读取两个简单的字符串。
现在当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
所以BaseUser 与setWallpaper 这件事完全无关。它只与我的 UI 活动有关(而且我也没有明确使用它)。
我尝试过的:
- 排除除简单字符串的 2 个设置器之外的所有内容,如上所述。
- 我想也许让
BaseUser类本身处理 Firestore 会导致问题,所以我尝试在课堂外做同样的事情。一样。 - 我尝试使用 Firebase 数据库而不是 Firestore。一样。
- 还有其他类继承
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