【问题标题】:Updating a document in cloud firestore更新 Cloud Firestore 中的文档
【发布时间】:2018-09-21 01:54:10
【问题描述】:

我想将服务器响应保存在客户端。我想在云 Firestore 中的现有文档中添加一个字段。这是我正在处理的代码。我在另一个项目中应用了相同的过程,它在那里运行良好。

public class Stripe extends AppCompatActivity  {
    FirebaseFirestore db;
    String d;
    private static final String TAG = "Stripe";
    private FirebaseAuth mAuth;
    Card card;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stripe);
        Bundle bundle = getIntent().getExtras();
        final int a= bundle.getInt("Amount");
        System.out.println(a);
        mAuth = FirebaseAuth.getInstance();
        final CardInputWidget mCardInputWidget = (CardInputWidget) findViewById(R.id.card_input_widget);
        Button button = (Button) findViewById(R.id.confirmation_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Bundle bundle = getIntent().getExtras();
                final int a= bundle.getInt("Amount");
                System.out.println(a);
                //final int a = Integer.parseInt(amt);
                card = mCardInputWidget.getCard();
                if (card == null) {
                    Log.e(TAG, "Invalid Card Data");
                }
                pay(a);
            }
        });
    }

    private void pay(final int a) {

        com.stripe.android.Stripe stripe = new com.stripe.android.Stripe(getApplicationContext(), "*********************");
        stripe.createToken(
                card,
                new TokenCallback() {
                    public void onSuccess(Token token) {
                        Toast.makeText(getApplicationContext(), token.getId(), Toast.LENGTH_LONG).show();
                        token.getId();
                        Map<String , Object> dataToSave = new HashMap<String, Object>();
                        final String token1 = token.getId().toString();
                        dataToSave.put("token",token1);
                        dataToSave.put("Amount",a);
                        FirebaseFirestore db = FirebaseFirestore.getInstance();
                        String UID = mAuth.getUid().toString();
                        Gson gson = new GsonBuilder()
                                .setLenient()
                                .create();

                        Retrofit.Builder builder = new Retrofit.Builder()
                                .baseUrl(" https://us-central1-deyapay-192704.cloudfunctions.net/stripePayMoney/")
                                .addConverterFactory(GsonConverterFactory.create(gson));
                        Retrofit retrofit = builder.build();
                        executeForm(token1,a,UID);

                        db.collection("deyaPayUsers").document(mAuth.getUid().toString()).collection("Stripe")
                                .add(dataToSave)
                                .addOnSuccessListener(new OnSuccessListener<DocumentReference>(){

                                    @Override
                                    public void onSuccess(DocumentReference documentReference) {
                                        Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId());
                                        d= documentReference.getId();
                                        System.out.println(d);

                                    }
                                }).addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Log.w(TAG, "error", e);
                            }
                        });
                    }

                    public void onError(Exception error) {
                        // Show localized error message
                        Toast.makeText(getApplicationContext(),
                                error.getLocalizedMessage(),
                                Toast.LENGTH_LONG
                        ).show();
                    }
                }
        );

    }
    private void executeForm(String Token, Integer Amt, final String UID){
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl("https://us-central1-deyapay-192704.cloudfunctions.net/stripePayMoney/")
                .addConverterFactory(GsonConverterFactory.create(gson));
        Retrofit retrofit =  builder.build();

        APIService apiservice=retrofit.create(APIService.class);
        Call<PostData> call=apiservice.savePost(Token,Amt,UID);
        call.enqueue(new Callback<PostData>() {
            @Override
            public void onResponse(Call<PostData> call, Response<PostData> response) {
                if(response.isSuccessful()){
                    response.body();
                    String dp = response.body().getToken();
                    Log.d(TAG,dp);
                    System.out.println(d);
                    DocumentReference dbRef  = db.collection("deyaPayUsers").document(UID).collection("Stripe").document(d);
                    dbRef
                            .update("TransactionId",dp)
                            .addOnSuccessListener(new OnSuccessListener<Void>(){
                                @Override
                                public void  onSuccess(Void aVoid){
                                    Log.d(TAG,"Documnetsnapshot successfully updated!");
                                }
                            })
                            .addOnFailureListener(new OnFailureListener(){
                                @Override
                                public void onFailure(@NonNull Exception e){
                                    Log.w(TAG,"Error updating document",e);
                                }
                            });
                    Intent i = new Intent(Stripe.this,generic.class);
                    startActivity(i);
                    Toast.makeText(Stripe.this,"success",Toast.LENGTH_SHORT).show();
                }
                else
                {

                }
            }
            @Override
            public void onFailure(Call<PostData> call, Throwable t) {
                t.printStackTrace();
                Log.e(TAG,t.toString());
            }
        });
    }
}

但是我遇到了这个错误-

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)”

此错误是在 DocumentReference dbRef 行的 onResponse 类中引发的。

这里发生异常-

DocumentReference dbRef  = db.collection("deyaPayUsers").document(UID).collection("Stripe").document(d);
                        dbRef
                                .update("TransactionId",dp)
                                .addOnSuccessListener(new OnSuccessListener<Void>(){
                                    @Override
                                    public void  onSuccess(Void aVoid){
                                        Log.d(TAG,"Documnetsnapshot successfully updated!");
                                    }
                                })
                                .addOnFailureListener(new OnFailureListener(){
                                    @Override
                                    public void onFailure(@NonNull Exception e){
                                        Log.w(TAG,"Error updating document",e);
                                    }
                                });

【问题讨论】:

  • 我猜您在分配“db”引用之前正在访问它,因此是 NullPointerException。您应该发布代码中发生异常的部分,并在代码中用注释标记它,以便我们看到它发生的位置

标签: android google-cloud-firestore


【解决方案1】:

根据@Rudiger 的第一条评论,使用以下代码在pay() 方法内声明和分配数据库引用,但不在execute() 方法内。

// declare and initializing variable
FirebaseFirestore db = FirebaseFirestore.getInstance();

有两种方法可以移除这个 NullPointerException:

  1. 您可以在您的类中声明 FirebaseFirestore db 作为全局变量,并在您的onCreate() 方法中将其初始化db = FirebaseFirestore.getInstance();,然后再调用@ 987654327@方法。

  2. 否则,您也可以在 execute() 方法中再次初始化并声明本地 db 变量。

【讨论】:

    【解决方案2】:

    您已在全局范围内声明的FirebaseFirestore db; 未初始化并在executeForm() 方法中使用,因此您在此行获取NPE 以供收集参考

    DocumentReference dbRef  = db.collection("deyaPayUsers").document(UID).collection("Stripe").document(d);
    

    为了避免 NPE 在 onCreate() 方法中初始化 db 变量,如

    db = FirebaseFirestore.getInstance(); 
    

    现在您的 db 引用不为空,如果在您的活动中的任何方法中使用,都不会给您 NPE。

    【讨论】:

      猜你喜欢
      • 2018-05-08
      • 2019-10-23
      • 2021-01-24
      • 2018-11-28
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2021-09-27
      相关资源
      最近更新 更多