假设我想删除Firebase存储中的条目以及Firebase数据库中的元数据.我应该这样彼此独立地删除它们:
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
String selectedKey = selectedItem.getKey();
StorageReference imageRef = FirebaseStorage.getInstance().getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete();
mDatabaseRef.child(selectedKey).removeValue();
}
Run Code Online (Sandbox Code Playgroud)
或者我应该将数据库删除部分放入存储删除方法的onSuccessListener中?
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
StorageReference imageRef = FirebaseStorage.getInstance().getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
}
});
mDatabaseRef.child(selectedKey).removeValue();
}
Run Code Online (Sandbox Code Playgroud) java android firebase firebase-realtime-database firebase-storage
由于ValueEventListener每次更新数据时都会触发,因此在显示Firebase Database时完成新上传时也会调用它。RecyclerView当发生这种情况时,我现在的方式会导致重复条目,因为Upload对象已经在mUploads List. 当上传完成后,整个数据库会再次查询,所有项目都会添加到已经存在的数据库中,ArrayList我不知道如何解决这个问题。我应该Arraylist在每次触发 ValueEventListener 时创建一个新的,还是需要一个完全不同的回调?它ValueEventListener还会干扰我的mAdapter.notifyItemRemoved通话,因为ValueEventListener一旦我删除某些内容,它就会被触发。
public class ImagesActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListener {
private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private ProgressBar mProgressCircle;
private DatabaseReference mDatabaseRef;
private FirebaseStorage mStorage;
private List<Upload> mUploads;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_images);
mUploads = new ArrayList<>();
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mProgressCircle = findViewById(R.id.progress_circle);
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
mStorage = …Run Code Online (Sandbox Code Playgroud) android firebase firebase-realtime-database firebase-storage
我正在使用 Firestore 构建一个聊天应用程序,每个聊天室都有一个参与者地图,如下所示:
键是用户对应的UID。我想使用此地图来决定哪个用户可以访问聊天。在我的安全规则中,我当前检查登录用户的 UID 是否存在于该映射中以允许读写访问:
allow read, write: if request.auth.uid in resource.data.participants
Run Code Online (Sandbox Code Playgroud)
但这仅检查用户是否在此地图中,而不检查该值是否确实为真。我也想检查一下。
我基本上想要的是这样的:
allow read, write: if resource.data.participants.request.auth.uid == true
Run Code Online (Sandbox Code Playgroud)
但这实际上行不通。如何使用当前用户的 UID 作为地图检查的键?
firebase firebase-security firebase-authentication google-cloud-firestore
当某个布尔变量为 true 时,我的一个可组合项中的文本会被删除。如何在TextStyle重组时为这种变化设置动画,以便线条淡入而不是突然出现和消失?
@Composable
fun MyComposable(
completed: Boolean
) {
val textStyle = TextStyle(textDecoration = if (completed) TextDecoration.LineThrough else null)
Text(
text = title,
color = textColor,
style = textStyle,
modifier = Modifier.align(Alignment.CenterVertically)
)
Run Code Online (Sandbox Code Playgroud) android android-jetpack-compose android-jetpack-compose-text
我是新手,所以请记住这一点。
我刚刚在我的主要活动中添加了一个片段(有史以来第一次)。该片段的容器是一个 FrameLayout,我只是将它放在现有的相对布局之上。我已经可以在显示片段和再次删除它之间切换。
只有一个问题:来自主要活动的相对布局的按钮通过片段可见,即使它具有背景颜色。
有没有一种简单的方法可以让按钮不通过片段显示(但当我删除片段时仍然可见)。我不想手动将它们设置为不可见和可见,因为它们仅在主活动中的某些情况下才会显示。
一种解决方案可能是用片段替换包含按钮和其他所有内容的布局。但我想知道是否有不同的解决方案,因为我的布局文件设置不正确,无法轻松实现。
我正在着手实现文件选择器。该createChooser方法采用CharSequence title,但它实际上并未在任何结果选择器中显示此标题(在多个 API 级别上进行测试)。
private void openFileChooser() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Image"), PICK_IMAGE_REQUEST);
}
Run Code Online (Sandbox Code Playgroud)
这个标题应该显示在哪里?
文件说
QueryDocumentSnapshot包含从Firestore数据库中的文档读取的数据,作为查询的一部分.保证文档存在,并且可以使用getData()或get()方法提取其数据.
QueryDocumentSnapshot提供与DocumentSnapshot相同的API表面.由于查询结果仅包含现有文档,因此exists()方法将始终返回true,而getData()将永远不会为null.
但它没有解释何时我应该使用一个而不是另一个.我想无论是在一SnapshotListener对Collection两者工作.
protected void onStart() {
super.onStart();
notebookRef.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot queryDocumentSnapshots, FirebaseFirestoreException e) {
if (e != null) {
Toast.makeText(MainActivity.this, "Error while loading!", Toast.LENGTH_SHORT).show();
Log.d(TAG, e.toString());
return;
}
String allNotes = "";
for (QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots) {
Note note = documentSnapshot.toObject(Note.class);
String title = note.getTitle();
String description = note.getDescription();
allNotes += "\nTitle: " + title + " Description: " + description;
}
textViewData.setText(allNotes);
}
});
}
Run Code Online (Sandbox Code Playgroud) 我根据Google的教程使用Play Billing Library 1.0实现了应用程序内购买.我只有1件商品可以购买,当它解锁时,我会显示一个Toast.LENGTH_SHORT长度的Toast消息.然而,Toast在那里呆了10秒钟,所以我认为它被多次调用.当我通过queryPurchases(如果有人先前购买并在此期间重新安装应用程序)解锁时,它不会发生.
任何人都知道为什么Toast会停留这么久/为什么它被多次调用?
在我的BillingManager类中:
@Override
public void onPurchasesUpdated(int responseCode, @Nullable List<Purchase> purchases) {
if (responseCode == BillingClient.BillingResponse.OK) {
for (Purchase purchase : purchases) {
handlePurchases(purchase);
}
mBillingUpdatesListener.onPurchasesUpdated(mPurchases);
} else if (responseCode == BillingClient.BillingResponse.USER_CANCELED) {
} else {
}
}
public void handlePurchases(Purchase purchase) {
//here could be validation on own server
mPurchases.add(purchase);
}
Run Code Online (Sandbox Code Playgroud)
主Activity实现BillingUpdatesListener:
@Override
public void onPurchasesUpdated(List<Purchase> purchases) {
for (Purchase purchase : purchases) {
switch (purchase.getSku()) {
case "premium":
unlockPremium();
break;
}
}
}
public void …Run Code Online (Sandbox Code Playgroud) 我的情况:我只想将分钟和秒格式化为时钟文本格式。当我使用 String.format 时,我收到警告“隐式使用默认语言环境是错误的常见来源”
我该怎么处理这件事?我必须添加 Locale.US 还是可以忽略它?我很困惑,因为没有答案我看到有人在使用 String.format(Locale.US, ...)
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format("%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
Run Code Online (Sandbox Code Playgroud) 从Firestore文档中查看此代码示例:
DocumentReference docRef = db.collection("cities").document("SF");
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
@Override
public void onComplete(@NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document != null && document.exists()) {
Log.d(TAG, "DocumentSnapshot data: " + document.getData());
} else {
Log.d(TAG, "No such document");
}
} else {
Log.d(TAG, "get failed with ", task.getException());
}
}
});
Run Code Online (Sandbox Code Playgroud)
https://firebase.google.com/docs/firestore/query-data/get-data
为什么检查一下document != null?如果我正确读取源代码(初学者),该exists方法将在内部检查无效.
我正在尝试在我的 Android 应用程序中实现按钮点击处理。
在包含我的按钮的 XML 布局文件中,我向我的ButtonXML 元素添加了以下行:
android:onClick="handleClick"
Run Code Online (Sandbox Code Playgroud)
我还在Activity使用此布局的 中定义了具有以下签名的方法:
public void handleClick() { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
但是,当我使用此代码运行我的应用程序时,它崩溃了。我能够通过将我的方法签名更新为以下内容来修复此崩溃:
public void handleClick(View v) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么我需要包含这个View参数?